# How OpenCut Handles TypeScript Strict Mode and Type Safety: A Complete Technical Guide

> Discover how OpenCut ensures type safety with TypeScript strict mode. Explore its tsconfig.json, UI components, routing, and form validation strategies for robust application development.

- Repository: [OpenCut.app/OpenCut](https://github.com/OpenCut-app/OpenCut)
- Tags: deep-dive
- Published: 2026-07-01

---

**OpenCut enforces TypeScript strict mode through a comprehensive [`tsconfig.json`](https://github.com/OpenCut-app/OpenCut/blob/main/tsconfig.json) configuration and propagates type safety across UI components, routing, and form validation by combining strict compiler flags with explicit type definitions and utility generics.**

OpenCut is an open-source video editing application that prioritizes **type safety** at every architectural layer. By enabling the full suite of strict compiler checks in [`apps/web/tsconfig.json`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/tsconfig.json) and leveraging typed primitives from libraries like `class-variance-authority` and `@tanstack/react-router`, the codebase eliminates implicit `any` types and catches type mismatches during compilation rather than at runtime.

## Strict Compiler Configuration

OpenCut’s web application uses a fully strict TypeScript configuration located in [`apps/web/tsconfig.json`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/tsconfig.json). The configuration sets `"strict": true`, which automatically enables `noImplicitAny`, `strictNullChecks`, `strictFunctionTypes`, and other strictness flags.

Additionally, the configuration includes several explicit flags to prevent unsafe patterns:

- **`"noUnusedLocals": true`** – Errors on local variables that are never read, eliminating dead code.
- **`"noUnusedParameters": true`** – Errors on function parameters that are never used, enforcing clean function signatures.
- **`"noFallthroughCasesInSwitch": true`** – Disallows fall-through in `switch` statements, preventing logic errors.
- **`"noUncheckedSideEffectImports": true`** – Prevents importing modules that have side effects without explicit `import type` declarations.
- **`"skipLibCheck": true`** – Skips type checking of declaration files to improve build speed while maintaining strict checks on project code.

These settings force developers to explicitly type every exported API and prevent accidental `any` leaks from untyped dependencies.

## Type-Safe Component APIs

OpenCut’s UI components combine primitive prop definitions with variant-based styling using **typed generics**. In [`apps/web/src/components/ui/button.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/components/ui/button.tsx), the component merges the base button primitive’s props with variant props generated by `class-variance-authority`.

```tsx
// apps/web/src/components/ui/button.tsx
import { Button as ButtonPrimitive } from "@base-ui/react/button"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "#/lib/utils.ts"

type ButtonProps = ButtonPrimitive.Props & VariantProps<typeof buttonVariants>

function Button({ className, variant = "default", size = "default", ...props }: ButtonProps) {
  return (
    <ButtonPrimitive
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  )
}

```

The `ButtonProps` type **inherits** the exact prop shape from `ButtonPrimitive.Props` and augments it with `VariantProps<typeof buttonVariants>`. This ensures that any variant name passed to the component (like `variant="destructive"`) is checked against the defined schema at compile time, preventing invalid string literals from reaching production.

## Generated Route Types

The routing layer in OpenCut achieves **end-to-end type safety** through `@tanstack/react-router` and its code generation. The file [`apps/web/src/routeTree.gen.ts`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routeTree.gen.ts) contains autogenerated interfaces that strictly define the shape of all application routes.

```ts
// apps/web/src/routeTree.gen.ts
export interface FileRoutesByFullPath {
  [fullPath: string]: RouteRecord
}
export interface FileRoutesByTo {
  [to: string]: RouteRecord
}
export interface FileRoutesById {
  [id: string]: RouteRecord
}
export interface FileRouteTypes {
  // Strict route definitions...
}

```

These interfaces ensure that route parameters, search params, and path definitions are type-checked throughout the application. Because `FileRouteTypes` provides explicit mappings, the TypeScript compiler can verify that `Link` components point to valid routes and that route parameters match their expected types.

## Utility Function Typing

Even small utility functions like `cn` (class-name merger) are written with **explicit type imports** to prevent arbitrary value acceptance. Located in [`apps/web/src/lib/utils.ts`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/lib/utils.ts), the function uses `ClassValue` from `clsx` to constrain inputs.

```ts
// apps/web/src/lib/utils.ts
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs))
}

```

The `ClassValue` type is a union that only permits strings, numbers, booleans, or arrays thereof. If a developer attempts to pass an object or other invalid type to `cn`, the TypeScript compiler flags the error immediately.

## End-to-End Form Validation

OpenCut extends **type safety** to form handling by combining **Zod** schemas with React Hook Form. The `zodResolver` from `@hookform/resolvers` creates a generic type that ties form data shapes directly to validation schemas.

```tsx
import { z } from "zod"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"

const schema = z.object({
  title: z.string().min(1),
  duration: z.number().positive(),
})

type FormValues = z.infer<typeof schema>

const form = useForm<FormValues>({ resolver: zodResolver(schema) })

```

The `FormValues` type is **inferred** from the Zod schema, ensuring that the `form` object’s `watch`, `setValue`, and `handleSubmit` methods only accept data matching the defined structure. This pattern, confirmed by the presence of `zod` and `@hookform/resolvers` in [`apps/web/package.json`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/package.json), prevents runtime validation errors by catching type mismatches during development.

## Summary

- OpenCut enables **full strict mode** in [`apps/web/tsconfig.json`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/tsconfig.json) with `"strict": true` and additional flags like `noUnusedLocals` and `noUncheckedSideEffectImports` to eliminate implicit `any` types and unsafe imports.
- UI components use **intersection types** combining primitive props with `VariantProps` to create strictly typed component APIs that catch invalid prop values at compile time.
- Route definitions rely on **autogenerated interfaces** in [`routeTree.gen.ts`](https://github.com/OpenCut-app/OpenCut/blob/main/routeTree.gen.ts) to ensure type-safe navigation throughout the application.
- Utility functions like `cn` use **explicit type imports** (`ClassValue`) to constrain inputs and prevent runtime class-name errors.
- Form validation leverages **Zod inference** with React Hook Form resolvers to maintain type safety from schema definition to submission handling.

## Frequently Asked Questions

### What strict TypeScript flags does OpenCut use?

OpenCut enables `"strict": true` in [`apps/web/tsconfig.json`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/tsconfig.json), which activates `noImplicitAny`, `strictNullChecks`, and `strictFunctionTypes`. Additionally, the project configures `noUnusedLocals`, `noUnusedParameters`, `noFallthroughCasesInSwitch`, and `noUncheckedSideEffectImports` to enforce clean, explicit code and prevent side-effect imports without type declarations.

### How does OpenCut ensure type safety in UI components?

The codebase uses **intersection types** that combine base primitive props (like `ButtonPrimitive.Props`) with `VariantProps` from `class-variance-authority`. This pattern in [`apps/web/src/components/ui/button.tsx`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/components/ui/button.tsx) ensures that variant names, sizes, and other props are strictly checked against defined schemas, preventing invalid values from being passed to components.

### How are routes type-checked in OpenCut?

OpenCut uses `@tanstack/react-router` to generate [`apps/web/src/routeTree.gen.ts`](https://github.com/OpenCut-app/OpenCut/blob/main/apps/web/src/routeTree.gen.ts), which contains explicit interfaces like `FileRoutesByFullPath` and `FileRouteTypes`. These generated types provide compile-time guarantees that route paths and parameters match the expected definitions throughout the application.

### What validation library does OpenCut use for form type safety?

OpenCut uses **Zod** combined with `@hookform/resolvers`. The `zodResolver` creates a generic link between the Zod schema and React Hook Form's `useForm` hook, allowing the form values type to be inferred via `z.infer<typeof schema>`. This ensures that form data, validation errors, and submission handlers are all strictly typed according to the schema definition.