An agent-native UI runtime for React.
React components you own — styled, dependency-free, and machine-readable. Each component arrives in your project as source, with its stylesheet, and with a contract describing what it is and what can safely be done to it.
It ships an MCP server, so Claude Code, Codex and Cursor can read that contract instead of guessing at it — and build a screen straight from a Figma design.
npx @grampro/kit add DataGridOr npx @grampro/kit add with no names, to pick from the list: type to search,
space to select, enter to install.
The source lands in component-lib/, or src/component-lib/ in a project
with a src/ folder; --dest puts it anywhere you like, and later installs
follow the first. There is no runtime package to depend on, and nothing to
wait for upstream when you need a change.
Upgrading from 2.1.0 or 2.2.0 — one line to change. Component CSS no longer lives in a cascade layer, because a layer loses to any unlayered reset and that broke Tailwind v3 and Bootstrap outright. Delete any
@layer gbs, utilities;you added, and import the generated barrel:@import "./component-lib/gbs.css";— with Tailwind v4, after the framework andlayer(components). The installer prints the line you need, andCHANGELOG.mdhas the detail.
Most component libraries are built for a human reading documentation. These are built to be operable by a program as well — a coding agent writing your UI, or a model driving a grid at runtime — without either one guessing.
Three things make that true, and all three ship today:
A passport per component. passport.json is generated from the TypeScript
source and drift-checked in CI: every prop with its real type, the events, the
slots, the data-* states, and the operations the component actually supports.
Generated, so it cannot quietly stop being true.
→ docs/component-passport.md
A runtime contract. The passport says what a DataGrid is. The runtime
contract says what this grid can do right now: these columns, these operators,
this state, this many rows. Counts and bounded summaries only — never your data.
→ docs/grid-agent-runtime.md
A validator between intent and action. Five layers — schema, reference,
coercion, policy, plausibility — stand between a requested operation and
anything happening. "1 lakh" becomes 100000 deterministically rather than by
a model's arithmetic. An operation on a column the host restricted is refused
with a reason. Nothing that fails validation runs.
The runtime ships no model, and most of it is useful anyway:
- Saved views and shareable URLs — the grid's whole state in a link
- Undo and redo across every operation, by snapshot
- An audit trail of what changed, in readable labels
- Confirmation before anything irreversible, with the affected row count computed from a real dry run
A model, when one is added, plugs into the front of that pipeline. It produces an intent, and the validator treats it exactly as it treats any other untrusted input. That is the point of the ordering.
An earlier version of this README called these components headless. They are not. They ship 27 stylesheets with a default look, theming and dark mode, and the word elsewhere in the ecosystem means no styles at all.
What is true is that the styling gets out of your way at three levels: CSS
variables, slot classes, and data-* state attributes. Nothing is
!important, and nothing needs beating on specificity.
Each component also has a framework-free core — createDialogStore(),
createGridEngine() — with no React imports, usable on a server. That part is
genuinely headless, and the component READMEs document it under "Headless use".
add <Component>... |
Copy components into the project, or update ones already there. A component you have edited is left alone unless you pass --force. --dest chooses where; --legacy reaches the 1.x set. |
doctor [Component...] |
What you changed in your copies, what the new version changes, and which of your call sites an update would break. --json for agents and CI. |
list |
What is available to add. |
skill |
Install the agent skill. --for claude,codex,antigravity narrows it. |
mcp |
Run the MCP server. Agents start this themselves; you rarely type it. |
mcp install |
Write the server's configuration for Claude Code, Codex and Cursor. |
secret set figma |
Store a Figma token in the OS credential store. Also get, list, remove. |
design <file> |
Split a whole-design Figma export into a folder of screens. |
passport --check |
Fail if a passport has drifted from its source. For CI, and after forking a component. |
npx @grampro/kit <command>, or grampro-kit once it is a dev dependency.
kit.gramproindia.com — usage and props per component.
In this repository:
docs/component-passport.md |
the generated contract, and why its text is data rather than instructions |
docs/grid-agent-runtime.md |
runtime contract, intent schema, the five validation layers, undo, saved views |
docs/grid-agent-evaluation.md |
the 230-case corpus and how a model gets measured against it |
docs/agent-native-architecture.md |
where this is going, and which parts are still proposal |
The catalogue, served to a coding agent on demand over the Model Context Protocol:
npx @grampro/kit mcp installThat configures Claude Code (.mcp.json), Codex
(.codex/config.toml) and Cursor (.cursor/mcp.json) in one command,
merging into whatever is already there.
Its seven tools answer what components exist (list_components), what a
component's props actually are (get_component), how it is used
(get_example, get_guidance), what a Figma frame contains
(figma_frame), and — the one that earns its place — whether the JSX an
agent just wrote matches the real API (validate_usage).
install_component copies what the design needs into your project, so an
agent can go from a Figma link to a working screen without you installing
anything first.
No dependencies, and it starts in about the time an empty Node process
takes. Full walkthrough, including a prompt to paste:
kit.gramproindia.com/mcp-server.
Details in tools/mcp/README.md, including what a tool
call can and cannot reach.
Use 2.7.1 or later. From 2.4.4 through 2.7.0, a crafted get_guidance
call could read any .md file the server could open. The
changelog explains how to check which version your agent
is running.
Grampro Kit on the Figma Community
In review — Figma is quoting a few weeks. Until it clears, clone this repository and import
figma-plugin/manifest.jsonthrough Plugins → Development → Import plugin from manifest... in the Figma desktop app. The build is committed, so there is nothing to compile.
Two jobs. It generates the whole design system inside Figma — 53 variables across light and dark, 13 text styles, 38 component sets — and it exports screens as JSON a coding agent can build from.
# in Figma: Grampro Kit → Export all screens for an agent → Save .json
npx @grampro/kit design ./design.jsondesign/
purchase-orders.json
suppliers.json
index.json every screen, the shared theme, the regions that repeat
The agent reads index.json to plan, then builds one screen at a time
against figma_frame, get_component and validate_usage. It needs no
Figma API token and makes no network requests of any kind.
Source is in figma-plugin/; the published listing is
what to install.
Install the skill once per project so a coding agent uses these components correctly instead of guessing at the API:
npx @grampro/kit skillIt writes the skill at the root of the project you run it in, in the place each agent looks:
| Agent | Gets |
|---|---|
| GBS SE Agent | .gbs/skills/gbs-components/ (canonical) |
| Claude Code | .claude/skills/gbs-components/ |
| Antigravity | .agents/rules/gbs-components.md |
| Codex | a marked block in AGENTS.md |
Pick a subset with --for claude,codex, or --for none for just .gbs/.
Commit the result so everyone's agent picks it up. Re-run to update; a file you
have edited is never replaced without --force.
The 2.x line is in active development and the next release will be a major version. What is built and tested:
- 27 components, source-first, zero runtime dependencies
- Passports for all 27, generated and drift-checked, and all 27 now carry the authored half too: what the component is for, what it supplies to assistive technology, and which props an agent may change without altering behaviour
- The DataGrid agent runtime: 21 operations, five validation layers, snapshot undo, and a frozen 231-case evaluation corpus
- The field runtime:
setValue,clear,focusand, where there is something to disclose,openandclose— on Input, Textarea, NumberInput, Checkbox, Switch, RadioGroup, Combobox and DatePicker. The same five layers, written once inshared/core/agentrather than eight times <DataGrid ai />— a natural-language box, driven by an adapter the application supplies. No model is bundled, downloaded or named.- WebMCP — one tool,
operate_grid, exposing the same validated boundary to a browser agent. Needs no model at all. <AgentSurface>— wrap a page and every field and grid in it describes itself to a browser agent, from its own props, and is operated through its own validator. One WebMCP tool,operate_page, for the whole page; no tool definitions to write- A model evaluation harness, with the measurements that justify both
Every producer — a model, a browser agent, a form — proposes. The validator authorizes. The executor mutates state. That boundary is the architecture, and it is why no AI path gets a second route into the component.
Nine of the 27 are agent-operable. The executor abstraction was the open
question — a grid is driven through an imperative API, and a field is not — and
it is settled: Combobox and DatePicker are driven through their handles,
Input, Textarea, Checkbox and Switch through the element their ref already
hands back, and NumberInput and RadioGroup, inside an <AgentSurface>, through
their own commit path — a number is not text, and a group is not one radio.
Neither the contract, the schemas, the validator nor the refusals know which.
Still open: the components whose value is in what they contain rather than what
they hold — Menu, Tabs, Accordion, Modal, FileUploader — and the question of
whether a form is better driven field by field or as one composite assembled
from several passports. The roadmap and its unresolved questions are in
docs/agent-native-architecture.md.
Install a component and the CLI writes gbs.css next to it, importing every
component stylesheet you actually installed. Add one line to your global CSS:
@import "./component-lib/gbs.css";That is all, for Tailwind v3, Bootstrap, and projects with no CSS framework.
Tailwind v4 is the one exception, because it puts its own utilities in a cascade layer. Import ours after the framework, inside Tailwind's components layer, so utilities still win:
@import "tailwindcss";
@import "./component-lib/gbs.css" layer(components);The installer detects which of these you need and prints it. gbs.css is
rewritten on every install, so the list stays correct as you add components.
Why it works this way. Component CSS ships unlayered. An unlayered rule
beats every layered rule regardless of specificity, so a library that puts its
rules in a cascade layer loses to any unlayered reset — Tailwind v3's preflight
and Bootstrap's Reboot both qualify. Unlayered, our rules win on ordinary
specificity (a class beats *), and your own CSS and utilities still override
them the normal way. layer(components) on the import is native CSS, and is
the standard way to place third-party CSS under Tailwind v4.
If you forget it on v4, the failure is small and local: the component renders
correctly, but a utility passed through className will not override it.
Every scrolling surface in the kit is thin by default, using the standard
scrollbar-width / scrollbar-color properties. Restyle them all from :root:
:root {
--gbs-scrollbar-width: auto; /* auto | thin | none */
--gbs-scrollbar-thumb: var(--gbs-accent); /* defaults to a muted accent */
--gbs-scrollbar-track: transparent;
}Add class="gbs-scroll" to your own scrolling areas to match. Scroll containers
the kit does not own keep the browser default — it never restyles scrollbars it
was not asked to.