Framer to TypeScript: what typed code you get from a Framer site

The TypeScript you get when you convert a Framer site to code, how strict it is, why code components are checked differently, and how to tighten types.

Published
Reading time
4 min
Deframer cover: “Typed code, honestly.” Beside it, a list of Typed props, CMS schema, Type check and Strict mode with Typed props selected
On this page7 sections

When you convert a Framer site with Deframer, every code file in the project is TypeScript: .ts and .tsx, plus .astro pages in the Astro export. Generated components get typed props, refs and rich-text properties where TypeScript can't infer them, and the project type-checks. It is not in strict mode by default, because the code components you wrote in Framer were never type-checked there; instead the project reports every error so you can tighten types file by file.

Deframer is an independent tool and is not affiliated with, endorsed or sponsored by Framer. It downloads code for sites you own or have permission to convert.

Why isn't Framer's own code typed?

Framer sites run on React, and code components are written in TypeScript-flavored files. But Framer compiles them without checking their types, so a component can publish fine while containing real type errors. The generated code for design components is also written for a runtime, not for people: props have internal ids, and many parameters are untyped.

A converter that wants a project to type-check has two jobs: make the generated code type-check honestly, and handle the code you wrote without pretending it is stricter than it is.

What the generated code looks like

Human names, typed props

Props and variants keep the names the designer gave them, so you read variant === "Desktop" or "D / Light", not ids. Where TypeScript can't infer a type, the converter writes one that states what the code already does. A few examples of the edits it makes:

Framer's generated code

In the project

A rich-text property declared as string

React.ReactNode, because instances pass elements

React.useRef<HTMLElement> attached to a <motion.div>

React.useRef<HTMLDivElement>

React.HTMLAttributes<React.HTMLDivElement>

React.HTMLAttributes<HTMLDivElement> (DOM types are globals)

A destructured parameter with no type that callers call with fewer props

Annotated so callers that leave props out still type-check

Animations use motion/react with typed transitions, for example a spring that keeps its stiffness, damping and mass:

ts
const transition1 = { damping: 60, delay: 0, mass: 1, stiffness: 400, type: "spring" } as const;

Typed content

Each CMS collection becomes two files: src/cms/<collection>.ts, a module with the schema that lists its fields in the CMS's own order (with each enum field's options and titles), and src/cms/<collection>.json, the records. The schema is plain TypeScript you can read, and it's the place to look when you add a field or move the content to a database. Framer CMS to JSON covers the format.

Typed routes

The route layer is typed by each framework's own tooling: App Router routes in Next.js, a generated route tree in TanStack Start, react-router typegen in React Router, and astro sync in Astro.

The tsconfig settings, and why

The tsconfig.json in every export sets strict: false. In the TanStack Start, Astro, React Router and Vite exports it also sets strictNullChecks: true, which TanStack Router requires and which the project's own code passes.

The site's own code is the exception. Code components and overrides you wrote in Framer land in src/code, and marketplace components in src/vendor, as source. Those were compiled by Framer without null checks, so they are checked the same way.

How type-checking runs

Framework

Command

What it does

Next.js

npx tsc --noEmit

Checks the whole project

TanStack Start

npm run typecheck

Builds once if the route tree is missing, then checks

Astro

npm run typecheck

astro sync, then checks

React Router

npm run typecheck

react-router typegen, then checks

Vite

npm run typecheck

Checks the project

In the non-Next exports, npm run typecheck runs a small script, scripts/typecheck.ts, that checks src/code and src/vendor the way Framer compiled them (browser globals, no strictNullChecks) and everything else with tsconfig.json. Every error is reported in tsc's usual format.

In the Next.js export, if the site has code components, next.config.ts keeps typescript: { ignoreBuildErrors: true } with a comment explaining why, so a type error in code Framer never checked doesn't block next build. npx tsc --noEmit still lists those errors.

A path to stricter types

You don't have to do this to ship, but if your team will maintain the site, it pays off.

  1. Run the check and save the output. Count errors per folder; most will be in src/code.
  2. Type your own components first. Replace any props with an interface. The addPropertyControls call in the same file is a good guide to which props exist and their defaults. Code components and overrides shows an example.
  3. Leave src/vendor for last. Marketplace code is third-party; consider replacing it with a maintained npm package instead of typing it.
  4. Turn on strictNullChecks, then strict, once the count is low, and fix what appears.
  5. In Next.js, remove ignoreBuildErrors once tsc is clean, so the build guards you from then on.
  6. Add the check to CI so new errors don't creep back. Preview deployments shows where it fits.

Does typed code help with AI editing?

Yes. Types tell tools like Cursor and Claude Code what a component accepts, and the type-check gives them, and you, a fast way to see when an edit broke something. Editing a Framer site with Cursor or Claude Code and writing an AGENTS.md for a converted site cover that workflow.

FAQ

Is the converted project JavaScript or TypeScript?

TypeScript. Every code file is .ts or .tsx, beside CSS modules and JSON content, and the Astro export adds .astro pages.

Why isn't strict mode on by default?

Because the site's code components were never type-checked in Framer, and switching on strict would make many of them fail on day one. The project reports every error instead, so you can fix them gradually.

Will type errors stop my build?

In Next.js, not when the site has code components: ignoreBuildErrors is kept with a comment. In the other exports, the build runs separately from npm run typecheck.

Are CMS records typed?

Each collection has a schema module beside its JSON records, listing every field and its type. Tightening that into a full TypeScript type for each record is a small, worthwhile change if you'll edit the content by hand.

Can I use the components in another TypeScript app?

Yes, with their CSS modules, the tokens in src/styles and the kit functions they import. See how to convert a Framer site to React.

Keep reading

All posts
  • Deframer cover: “Lose the badge. Two real ways.” Beside it, two cards, Paid plan or Own code, with Own code selected

    Branding6 min read

    How to remove the "Made in Framer" badge

    The "Made in Framer" badge goes away on a paid Framer site plan. Here is how that works, why CSS tricks are a poor idea, and the no-badge route of owning code.

  • Deframer cover: “Keep counting after the move.” Beside it, a list of Framer stats, GA4, Custom code and Your analytics with Your analytics selected

    Analytics5 min read

    Analytics after moving off Framer

    What happens to analytics when you move a Framer site to code, where tracking snippets end up, and how to set up GA4, Plausible or PostHog.