Search documentation

Search docs pages and sections

  • Docs home
Figma Kit
  • Getting started
  • Styles
  • Variables
  • Typeset
  • Theming
  • Components
  • Icons
  • Development
  • Updates
Registry
  • Pro Blocks
  • Templates
  • Themes
Plugin
  • Introduction
  • Generate code
  • Manage variables
  • Typeset
  • Select and install Pro Blocks
  • Security
Agent Skills
  • Agent Skills
DS Manager
  • DS Manager
  • Quickstart
  • Interface tour
  • Styles and icons
  • Colors and tokens
  • Typography
  • Radius, spacing and shadow
  • Brand
  • Editing components
  • Variants and states
  • Breakpoints
  • Custom components
  • ProBlocks
  • Design agent
  • Lint locks
  • Publish and install
  • Share links and forks
  • Plans and limits
Licensing
  • Licensing agreement
  1. Documentation
  2. Lint locks

Menu

HomePreviewPricingRoadmapHelp & Contact

Products

shadcn Componentsshadcn BlocksAgent SkillsDS ManagerNewFigma Pluginshadcn Templates

Resources

shadcn ThemesTheme GeneratorDocsAcademyBlogIcons

Legal

Licensing AgreementTerms & ConditionsPrivacy PolicyCookies

Components

AccordionAlertAlert DialogAspect RatioAttachmentAvatarBadgeBreadcrumbBubbleButtonButton GroupCalendarCardCarouselChartCheckboxCollapsibleComboboxCommandContext MenuData TableDate PickerDialogDrawerDropdown MenuEmptyFieldFormHover CardIcons - HugeIconsIcons - Lucide IconsIcons - Phosphor IconsIcons - Remix IconIcons - Tabler IconsInputInput GroupInput OTPItemKbdLabelMenubarMessageMessage ScrollerNavigation MenuPaginationPopoverProgressQuestionnaireRadio GroupResizableScroll-areaSelectSeparatorSheetSidebarSkeletonSliderSonnerSpinnerSwitchTableTabsTextareaToastToggleToggle GroupTooltipTypesetTypography

Landing Page Blocks

404 SectionsBannersBento GridsBlog SectionsCTA SectionsComparison SectionsContact SectionsEmpty LP SectionsFAQ SectionsFeature SectionsFootersGallery SectionsHeader SectionsHero SectionsLP NavbarsLanding Page ExamplesLogo SectionsPatternsPricing SectionsRich Text SectionsStats SectionsTeam SectionsTestimonials Sections

Application Blocks

App ShellsApplication ExamplesButtonsCardsDescription ListsEmpty SectionsNavbarsPage HeadersSection FootersSection HeadersSectionsSettingsSign inSign upTable Headers

E-commerce Blocks

CheckoutsExamplesIncentivesOrder Summary SectionsProduct Category SectionsProduct HeadersProduct List FiltersProduct List SectionsSale SectionsShopping CartsStore Navbars

This project is independent and not affiliated with Figma or shadcn/ui.
Copyright © 2026 Matt Wierzbicki

Lint locks

Lint locks set which properties AI agents may change on each shadcn/ui component. The DS Manager agent obeys them, and so do Claude and Cursor in your project.

A lint lock says that agents may not change one kind of property on a component, such as Color on Card. The agent in DS Manager refuses a locked change and tells you why. The locks also publish with your registry as a policy for @shadcn/lint, so Claude Code, Cursor or any other agent that runs your linter gets them as lint errors.

The Lint tab on the Button page, with Layout under Agents can change and Color, Type, Spacing, Shape, Effects and Motion under Agents can't change

What you can lock

Locks work per category. There are seven:

CategoryCovers
Layoutmargin, width and position
Colorbackground, text and border
Typesize, weight and leading
Spacingpadding and gap
Shaperadius, border and ring
Effectsshadow, opacity and blur
Motiontransition and animation

You can lock a category for every component, for one component, or for one part of a component (Card title, Dialog footer). A part follows its component until you change it.

Turn locks on

Locks are off in a new system. Open any component page, switch to the Lint tab and click Turn on next to "Locks are off".

Turning locks on leaves Layout open and locks the other six categories on every component. From there you open what agents should be allowed to change.

Lock or unlock a property

  1. Open a component page, for example Card.
  2. Open the Lint tab in the right rail, or press 4.
  3. Pick what to edit in the Part menu: the component itself or one of its parts. ⌘-clicking a part on the canvas, or picking it in Component Layers, selects it here too.
  4. Click a category chip to move it between Agents can change and Agents can't change.

Each click is one undo step. Hover a chip to see an example change for that category drawn on the selected part. A part that differs from its component says so in the chip's tooltip ("Differs from Card").

To unlock, click the chip again in Agents can't change.

Try a change previews any edit against your locks without saving it. Pick a preset in Change (Wider, Red text, Bigger text, More padding, Round corners, Shadow) or type your own class under Custom class. The canvas outlines the part with the change applied and shows whether it is allowed. When it isn't, Copy message copies the sentence an agent would get.

All locks on one page

Brand → Lint shows the whole policy. The header switches between two views.

Locks is a table with one row per component and one column per category. The first row, Every component, is the default the others inherit. Click a cell to lock or unlock it; its tooltip reads, for example, "Locked. Agents can't change Color on Card. Click to unlock." Inherited values are muted and exceptions are drawn solid with a dot, so they stand out. Show parts opens a component's parts, and the search field filters the table.

Rules sets how strict the linter is. Strictness offers three presets (Relaxed, Balanced, Strict). Below it, each of the six rules has Off, Warn and Block:

  • Restyling: components keep their look. This is the rule your locks belong to.
  • Raw colors: colors come from your tokens, not values like red-500.
  • Made-up sizes: sizes come from your scale, not values like p-[13px].
  • Inline styles: styles go in classes, not a style attribute.
  • Typos: every class must be one Tailwind or your system can make.
  • Dynamic classes: class names are written out in full.

Block means agents must fix it. Warn means agents may ignore it. With Restyling at Off, no lock applies.

The Actions panel has three buttons. Suggested contracts… adds starting locks for components that have none yet and leaves the ones you changed alone. Set up with the agent opens the Agent tab, where the agent asks how pages may restyle your components and then writes the policy (this needs Pro). Clear all… turns every rule off and removes every lock; one undo brings it all back.

What the agent does at a lock

With Restyling at Block, the agent checks every class it would add, swap or remove on a component. If a change hits a lock, the whole edit is refused and nothing is applied. The agent tells you which lock stopped it:

Locked. Agents can't change Color on Card. Unlock it on the Lint tab first.

The Agent tab on the Button page after a request to make the default Button amber: the agent replies that Color is locked on Button and points to the Lint tab, and the buttons on the canvas keep their color

If one request mixes locked and open changes, nothing lands, and the agent can send the open changes again on their own. Some styles are shared between components: Button's radius also sets Button Group's outer corners, for example. A rounder Button is refused when Shape is locked on Button Group, even if it is open on Button.

With Restyling at Warn, the edit goes through and the reply says so: "Locked. Agents get a warning if they change Color on Card."

Locks bind agents only. Your own edits in the Style tab are never blocked. ProBlocks and custom components are not covered by locks.

Locks in your project

When the policy has at least one rule on, publishing adds it to your registry as design-system.lint.json. The install command writes that file into the project root and adds @shadcn/lint as a dev dependency.

The registry can't write your linter config, so you add it once. Open Get code and go to the Lint tab:

  1. Under Install the linter, pick ESLint or Oxlint and run the command, for example:

    pnpm add -D @shadcn/lint eslint @typescript-eslint/parser
    
  2. Copy the config file the tab shows (eslint.config.mjs or .oxlintrc.json) into the project root. The ESLint version:

    import policy from "./design-system.lint.json" with { type: "json" }
    import { plugin as shadcn } from "@shadcn/lint"
    import tsParser from "@typescript-eslint/parser"
    import { defineConfig } from "eslint/config"
    
    export default defineConfig([
      {
        files: ["**/*.{js,jsx,ts,tsx}"],
        languageOptions: { parser: tsParser, parserOptions: { ecmaFeatures: { jsx: true } } },
        plugins: { shadcn },
        settings: policy.settings ?? {},
        rules: policy.rules,
      },
      ...policy.overrides,
    ])
    
  3. Add your lint command as the project's lint script.

  4. Add this line to your project's AGENTS.md, so agents run it:

    After making changes, run `npm run lint` and fix all errors.
    

From then on, an agent that passes a locked class to a component, like bg-red-500 on a Card, gets a lint error and has to fix it. The components and blocks the registry installs in components/ui and components/blocks may style themselves; your own code gets every rule.

To change a lock later, edit it in DS Manager, publish again and rerun the install command. The policy file updates with the rest of the system.