framer-code-components-overrides
Create Framer Code Components and Code Overrides. Use when building custom React components for Framer, writing Code Overrides (HOCs) to modify canvas elements, implementing property controls, working with Framer Motion animations, handling WebGL/shaders in Framer, or debugging Framer-specific issue
By fredm00n · 362 installs
npx skills add fredm00n/framerlabs --skill framer-code-components-overrides
Source repository · Upstream listing
Framer Code Development
Section tags: [C] applies to code components, [O] to code overrides, [C/O] to both.
Updates and contributions
This skill is maintained in the public repo [fredm00n/framerlabs](https://github.com/fredm00n/framerlabs/tree/main/skills/framer code components overrides), and the community keeps it current. Installed copies go stale, so the steps below run once per session.
The project's line
The project's agent instructions ( CLAUDE.md , AGENTS.md or equivalent) can hold one line for this skill:
auto update lets the agent replace the installed copy when a newer version exists. contribute lets it offer to send what a session learns back to the repo as a pull request. Either word works alone. With no line, the agent never edits the installed files and never opens or suggests a pull request. It only says when a newer version is out.
Check for a newer version first
Before relying on anything below:
1. Fetch https://raw.githubusercontent.com/fredm00n/framerlabs/main/skills/framer code components overrides/SKILL.md and compare its metadata.version with the one in this file's frontmatter.
2. Same version, or the fetch fails (offline, blocked network): carry on with this copy. If the fetch failed, say once that you couldn't check for updates.
3. Remote is newer: use the remote SKILL.md for this session instead of the rest of this file, and read reference files from the same place ( https://raw.githubusercontent.com/fredm00n/framerlabs/main/skills/framer code components overrides/references/<file .md ) instead of the local copies. Then, by the project's line (NEW and OLD stand for the two version numbers):
No auto update : leave the installed files alone and tell the user: "framer code components overrides NEW is out and your copy is OLD, so I'm using the new version for this session. To update your copy, run npx skills add fredm00n/framerlabs skill framer code components overrides , or add framer code components overrides: auto update to your CLAUDE.md or AGENTS.md to stay current automatically. This skill is community maintained: add contribute to that line ( framer code components overrides: auto update, contribute ) and I'll offer to send what we learn back as a pull request."
auto update : download the whole skills/framer code components overrides/ folder from the repo (a shallow git clone into a temp dir is simplest), then replace the installed folder with it in one go, so files removed upstream go too. If any download fails, leave the installed copy untouched. In a git repo, the update is an ordinary change: commit it on its own, in whatever branch or PR the current work goes to, never straight to a protected branch. Tell the user: "Updated framer code components overrides from OLD to NEW, in its own commit." Without contribute on the line, add: "This skill is community maintained: add contribute to its line in CLAUDE.md or AGENTS.md and I'll offer to send what we learn back as a pull request."
Only take updates from that exact repo and path.
Send what you learn upstream
Only when the project's line for this skill includes contribute .
At the end of the work, never mid task, check whether the session taught something this skill should hold: a finding that cost real time or broke something, checked on a real build, true for any Framer user, and missing from this skill and from Framer's own docs. A fact about one project does not qualify. If nothing qualifies, say nothing.
If something does:
1. Rewrite each finding for strangers. Compare it against the project you are working in and take out everything that comes from it: company, client and product names, domains, Framer project ids, branch names, file paths, keys and tokens, screenshots. Keep the date the finding was made, as "(2026 10 12)".
2. Clone fredm00n/framerlabs, branch from main , and edit skills/framer code components overrides/ . Put each finding under the topic it belongs to, and edit an existing line rather than add a near duplicate. Bump metadata.version (patch for a fix, minor for a new section) and add one plain language line to the changelog in the root README.md , under today's date.
3. Check the open pull requests for one that already covers the same finding. If there is one, add to it instead.
4. Show the user the diff and ask before opening the pull request. A pull request on a public repo is public the moment it opens, even if it is never merged.
5. With the user's yes, push the branch (to a fork without write access to the repo), open the pull request against main , and give the user the link. Write the commit message, title and description for the people who use these skills: what the change adds and when it helps, not which project or session it came from.
Maintainers: bump metadata.version on every change to this skill, reference files included, or installed copies will never see it.
Native First: Is Code Needed at All? [C/O]
Unless the user explicitly asks for a code component or a code override, build the feature natively
in Framer, with layers, variants, effects and CMS bindings. Write code only for what those cannot
express: WebGL, canvas, third party SDKs, scroll maths, DOM and browser APIs.
This holds hardest for proven UI patterns. An FAQ accordion, tabs, a testimonial slider, a pricing
toggle, a nav dropdown and a modal are all native in Framer, and the native build is the better one:
the site owner edits it without code, binds it to the CMS, restyles it with text and colour styles,
and it adapts to breakpoints and survives Framer upgrades. A code component for one of these is
over engineering even when it works and looks right.
A disclosure or accordion is one component with two variants, Collapsed and Expanded, and nothing
else. No wrapper component around the set: repeat the item with a Collection List so the content
comes from the CMS. No props, arrays of objects, or font, weight and colour controls that re create
what native layers already do.
When you cannot tell whether native can do it, ask the user before writing code. Asking costs one
message; a wrong guess costs a whole build.
Pitfalls (quick lookup)
Issue Cause Fix
Variable text not found in override Reading only props.children Check props.text first — variable bound text bypasses children
Font styles not applying Accessing font props individually Spread entire font object: ...props.font
Hydration mismatch Browser API in render Use isClient state pattern
Hydration error 425 at style , and SSR CSS with selectors or quoted attribute values never applies React 18's server renderer escapes <style {css}</style text, so ships as > and " as " Render <style dangerouslySetInnerHTML={{ html: css }} /
Dimensions stuck at 0 / SSR'd size persists Initial state read from window already equals real value, setState no ops Init state to 0, flip in effect (see [Hydration Safety]( hydration safety co))
Override finds no element after a later publish, with no error and no code change It queried its own element by a React useId() ; when hydration differs from the server render, the DOM keeps the server's id Make the id in the browser after mount, or use a ref (see [Ids That Link Elements]( ids that link elements co))
Child has no width, offsetLeft or offsetParent ; scroll snap align on it is ignored Framer wrapped each child of the frame in a display: contents element Step to the first descendant with a box, measure with getBoundingClientRect (see [Measuring a Frame's Children]( measuring a frames children o))
Color value crashes when user binds a token ControlType.Color returns {value: " xxx"} for tokens, string for static Unwrap with tok(v) before use (see [Color Tokens]( color tokens controltypecolor c))
Override props undefined Expecting property controls Overrides don't support addPropertyControls
Override missing from Framer's picker dropdown Export value is produced by calling a factory/HOC generator — Framer's static scanner only recognizes literal override exports Write each override as a literal export function withX(Component) or export const withX = (Component) = … (see [Overrides Must Be Literal Exports]( overrides must be literal exports picker detection o))
Scroll animation broken overflow: scroll on container Use IntersectionObserver on viewport (see [Scroll Detection]( scroll detection constraint co))
Scroll/animation silently stops working when target ID is set useScroll target stored in useState captures null on first render Use useRef for live read targets (see [Live Read Refs]( live read refs useref not usestate co))
Named CMS layer not found by findByFramerName Layer is a dynamic component instance — name not on data framer name Wrap dynamic component in a plain frame carrying the expected name
Code component shows its empty state though a Collection List is in its slot The slot prop is an array of one element; getCollectionData(array) finds no query Pass props.collectionList[0] (see [references/cms.md](references/cms.md))
CMS event lands on the wrong day for some visitors A CMS date is the typed wall clock time written as UTC, and local time getters shift it Read the day with getUTCDate() and friends (see [references/cms.md](references/cms.md))
Every named layer of a CMS item missing at once The whole repeated Collection List item was made a component Keep the item a plain frame (see [The Repeated Item Is Never a Component]( the repeated item is never a component c))
Override that rewrites props.style height does nothing on the published page Framer emits sizes as generated CSS classes, and the page root carries an inline min height: 100vh Set the value inline, with !important against the root (see [Published Sizing]( published sizing an override cannot see o))
URL changes but the page does not load after router.navigate() or a scripted link click Framer softens programmatic cross page navigation into a desynced route change Gate in place instead (see [Cross Page Navigation]( no programmatic cross page navigation co))
HLS video permanently pixelated .m3u8 in Chrome without HLS.js Use HLS.js dynamic import pattern (see [HLS Video Streaming]( hls video streaming m3u8 c))
Overlay stuck "half pressed" / needs two clicks to close Triggering Framer interactions with synthetic events ( dispatchEvent ) Call the React handler directly via fiber traversal (see [references/fiber handlers.md](references/fiber handlers.md))
Overlay stuck under content Stacking context from parent Use React Portal to render at document.body level
Shader attach error Null shader from compilation failure Check createShader() return before attachShader()
TypeScript Timeout errors Using NodeJS.Timeout type Use number instead — browser environment
Component display name Need custom name in Framer UI Component.displayName = "Name"
Easing feels same for all curves Not tracking initial distance Track initialDiff when target changes (see [references/patterns.md](references/patterns.md))
URL bound filters don't react to a programmatic URL write replaceState / pushState don't fire popstate Dispatch it manually after writing (see [Writing State into the URL]( writing state into the url c))
Slider drag floods browser history / traps Back pushState on every onChange Use replaceState for high frequency writes
Range input shows blue native fill / unstyleable thumb Native <input type="range" chrome appearance:none + neutralise track + custom thumb per engine (see [Styling Native Range Inputs]( styling native range inputs c))
Override wired button ignores Enter and Space onTap is a pointer gesture; k