by Zohaib Ahmed
What if your users could build their own features?
Inspired by the “claw” wave that OpenClaw started — where AI agents do real work on your behalf — OnClaw brings that same idea to SaaS products. It drops a ⌘K command bar into any app so your users can build their own features in plain English. Real components, real data, real code. Not mockups. Not templates. Actual code, in production.
See it in action
Two real demos. Just ⌘K and plain English to complete feature.
Adding a new component
A user clicks Edit on a project board and types “show me at a quick glance how many tasks are done.” OnClaw generates a task completion tracker in real-time and drops it right into the board.
Editing an existing component
Same app, different interaction — the user describes a change to an existing component and it updates in place. No page reload, no deploy.
The thesis
Salesforce didn’t become a $300 billion company because of CRM. CRM existed before Salesforce. It became a $300B company because every customer got their own version. Custom objects. Custom fields. Custom workflows. Custom reports. All without writing code. The platform was the product, not the CRM.
That created insane stickiness. Your Salesforce instance is YOUR Salesforce. It has your workflows, your fields, your automations. Switching cost is astronomical because you’d lose all of that. It also created an entire ecosystem — 500,000+ certified Salesforce admins became a career. Because the customization layer was so deep, it needed specialists.
But there was always a bottleneck. Every customization required an admin. A specialist. Weeks of configuration. The sales rep who needed a custom report couldn’t just build one — they had to file a request and wait.
I kept running into this pattern. At every company I worked at, the same story: users know exactly what they need, but they can’t build it. They file tickets. They wait for the next sprint. They get something close to what they wanted, but not quite, because requirements got lost in translation between the person who needed the feature and the person who built it.
Most SaaS apps are one-size-fits-all. That’s wrong. Or rather, it’s a compromise we accepted because the alternative — letting every user customize everything — was too expensive to build and too complex to maintain. The Salesforce approach works, but it requires an army of admins and a decade of platform investment.
LLMs change the economics completely. A user doesn’t need to learn a configuration UI or a custom formula language. They describe what they want in English. The model generates a real React component that queries real data through a context API you define. No admin layer. No configuration screens. No weeks of waiting.
I’m calling this user-driven engineering. Not “no-code” — that implies dumbed-down tools with ceilings. Not “AI-powered” — that’s a meaningless modifier at this point. User-driven engineering means: the person who needs the feature is the person who builds the feature. The developer’s job shifts from building every feature to building the platform that makes features buildable.
OnClaw is my attempt to make this practical. It’s a full-stack toolkit — a frontend component system plus a backend that handles auth, context, and code generation. You install it, define slots in your UI where user-generated components can live, and expose a context object with your queries and actions. Users hit ⌘K, describe what they want, and get a working component that’s saved to your codebase. Not some sandboxed iframe. Real code.
Think about what happens over time. User A builds a deal velocity tracker. User B builds a custom lead scoring view. User C builds a pipeline forecast widget. After three months, every user has a completely different app tailored to how they work.
Now try switching to a competitor. You’d lose all of that. Not because of data lock-in — because of workflow lock-in. Your tools work the way your brain works. That’s stickier than any data export.
The most valuable SaaS companies aren’t selling software. They’re selling a platform that becomes your software. Salesforce. Notion. Airtable. Figma. The next wave does this with AI. Every user gets their own version. That’s the whole idea.
Setup
OnClaw works in two modes: server-side with a Next.js API route (full power — auth, rate limiting, context API), or client-only for quick prototyping with just a provider and an API key.
The init command
This is the interesting part. npx onclaw init doesn’t ask you a bunch of config questions. It uses Claude to actually read your codebase — your schema files, your ORM, your auth setup, your page components — and generates a complete integration. It writes three files:
.onclaw/project.json— a manifest describing your schema, relations, and UI patterns. This gets injected into every LLM prompt so generated components understand your data model.src/onclaw/context.ts— typed query and action functions that act as the security boundary. Generated components can only call what you expose here.- An API route wired to your auth with rate limiting.
The AI scans for Drizzle, Prisma, Mongoose, raw SQL, in-memory stores — whatever you’re using. It finds your auth (NextAuth, Clerk, Supabase, custom JWT) and wires it in. It even reads your page components to figure out where to place slots. You can edit everything it generates — it’s just regular TypeScript.
$ npx onclaw init
◆ Scanning project...
│ Found: Next.js 15, Drizzle ORM, PostgreSQL, NextAuth
│ Schema: 6 tables (users, deals, contacts, activities, teams, notes)
│ Auth: NextAuth with Google + credentials
│ Pages: /dashboard, /deals/[id], /contacts, /settings
│
◆ Generating integration...
│ Created .onclaw/project.json (manifest)
│ Created src/onclaw/context.ts (12 queries, 4 actions)
│ Created app/api/onclaw/[...onclaw]/route.ts
│
◆ Done. Press ⌘K in your app to start building.Server-side mode (recommended)
The init command generates this for you, but here’s what it looks like. The API route handles auth, rate limiting, and proxies LLM calls so no API keys touch the client:
// app/api/onclaw/[...onclaw]/route.ts
import { createOnClawHandler } from "onclaw/next";
import { createContext } from "@/onclaw/context";
export const { GET, POST } = createOnClawHandler({
provider: "anthropic",
apiKey: process.env.ANTHROPIC_API_KEY!,
context: createContext(),
auth: async (req) => {
const session = await getServerSession(req);
if (!session?.user) throw new Error("Unauthorized");
return { userId: session.user.id };
},
rateLimit: { maxGenerations: 20, windowMs: 3600000 },
});The context API is where you control what generated components can access. This is the security boundary — no raw SQL, no arbitrary imports:
// src/onclaw/context.ts
export function createContext() {
return {
queries: {
getDeals: (filters) => db.select().from(deals).where(filters),
getContacts: (search) => db.select().from(contacts),
getRevenue: (period) => db.select().from(revenue).where({ period }),
},
actions: {
updateDealStage: (id, stage) =>
db.update(deals).set({ stage }).where(eq(deals.id, id)),
},
};
}Then wrap your page and drop in slots:
import { OnClawProvider, Slot } from "onclaw";
export default function Dashboard() {
return (
<OnClawProvider userId={session.user.id}>
<h1>Dashboard</h1>
<div className="grid grid-cols-2 gap-4">
<Slot id="metrics" />
<Slot id="chart" />
</div>
<Slot id="table" />
</OnClawProvider>
);
}Client-only mode
If you just want to try it without setting up a server route — maybe you’re prototyping, or you’re not on Next.js — you can pass the API key directly. No server route, no context API. Components generate against a static schema you provide:
import { OnClawProvider, Slot } from "onclaw";
export default function App() {
return (
<OnClawProvider
apiKey={process.env.NEXT_PUBLIC_ANTHROPIC_KEY}
userId="user-123"
schema={{
tables: ["deals", "contacts", "revenue"],
descriptions: { deals: "Sales pipeline deals with stage, value, owner" },
}}
>
<Slot id="main" />
</OnClawProvider>
);
}Client-only mode exposes the API key to the browser. Fine for prototyping, not for production. Use server-side mode for anything real.
What gets generated
When a user types “show me a revenue chart by month” into ⌘K, OnClaw generates a real .tsx file. Not a template. Not a mock. A React component that calls your context API with your actual data:
// onclaw-generated/revenue-chart.tsx (auto-generated)
export default function RevenueChart({ ctx }) {
const [data, setData] = useState([]);
useEffect(() => {
ctx.queries.getRevenue({ period: "monthly" }).then(setData);
}, []);
return (
<div>
<h3>Revenue by Month</h3>
<BarChart data={data} x="month" y="revenue" />
</div>
);
}The file is saved to disk. You can inspect it, edit it, commit it. It’s your code now — OnClaw just wrote the first draft.