Migrating from Legacy Code
Coming from legacy code in Framer there are few changes to aware of in order to take full advantage of the new features.
#Overview
With the code improvements, we made a few changes to how code in Framer works. Your old code and packages will continue to work for a long time, but to get the latest features (fast editing, instant sharing) you'll have to bring them over.Every new project (created after the date above) will have the new code options enabled. If you are working in a project with legacy code, it will show a legacy badge on top of the document. To bring code over, simply create a new project and copy and paste the code over. Almost everything should simply work, minus the few gotchas below.
#Code
#File Paths
Relative imports like import { cats } from "./dogs"
now need to have the file extension at the end, for example import { cats } from "./dogs.tsx".
#Framer Motion
Previously you may have imported Framer Motion-related items from the Framer Library using import { motion, useTransform } from "framer"
. These imports can now be imported directly from "framer-motion"
like so import { motion, useTransform } from "framer-motion"
#Framer Library
We used to rely on the Framer library full of custom components (like <Frame />
and <Stack />
) and utility functions. Going forward we decided to stay as close to JavaScript, React, and Framer Motion as possible to keep things simple, stable, and production-ready.
#Moving from Frame to div
While our Framer Library components will be supported for a long time, you'll see us move to standards and we recommend to do the same:
<Frame />
becomes<div />
or<motion.div />
(for animations) with standard css styling.<Stack />
optionally becomes<div />
with css flexbox.
All these standard elements will support advanced features like auto sizing out of the box.
Here is a basic example of using flexbox to align your content in a horizontal row, similar to how you would use <Stack direction="horizontal" distribution="space-around" />
// <Stack direction="horizontal" distribution="space-around" />
export function Component(props) { const list = [1, 2, 3, 4]
return ( <div style={{ display: "flex", justifyContent: "space-around" }}> {list.map(() => ( <div style={{ width: 50, height: 50 }} /> ))} </div> )}
You can also build something more re-usable to use in your components. Here is an example of an <HStack />
component that implements a gap
property.
If you build a custom component to suit your needs, you can use the "Copy Import" button in the toolbar to use it in your other components.
// <HStack gap={0}/>
function HStack(props) { const { style, children, gap = 0 } = props const childCount = React.Children.toArray(children).length
return ( <div style={{ display: "flex", ...style }}> {React.Children.map(children, (child, i) => React.cloneElement(child, { style: { ...child.props.style, marginRight: i < childCount - 1 ? gap : 0, }, }) )} </div> )}
#Packages
#Migrating existing Packages
Packages will continue to work for the foreseeable future, however, if you want to move them over to the new system we recommend moving them on a component by component basis and converting them to the new patterns on this page.