For Engineering
Rough for Engineering teams
What integrating Rough actually looks like — where it fits in your stack, what you have to build, and what you don't.
The honest pitch
You probably don't want to build a plugin system. They're large, they're long-lived, and they outgrow whatever architecture you initially picked. Rough is a way to get the customer-extensibility surface without paying for that.
What you're integrating is a small SDK and a few clearly-bounded components. What you're not integrating is a sandbox, a runtime, a builder UI, a versioning layer, or any of the operational machinery behind it.
What you actually do
A Rough integration has three steps:
-
Install
@roughapp/featureand callinitRough(...)with your project credentials. - Define a tool list — the queries, mutations and subscriptions you want to expose to Features. Each tool has a Zod input/output schema and an implementation that calls into your existing code.
-
Mount a
<RoughSurface>wherever you want Features to appear. Pass the tool list and any context the Surface needs.
That's the core integration. Everything else — building Features, hosting them, sandboxing them, generating types for them — is on Rough's side.
What lives where
- Tool implementations live in your codebase. They run in your process, with your auth, your validation, your rate limits. Rough doesn't impersonate users or bypass any of that.
- Feature code runs in an isolated runtime. Specifically,
a sandboxed iframe with a typed
postMessagebridge (@roughapp/iframe). It can't touch host DOM, host cookies, or anything outside the bridge. - The Surface is a Svelte component. If your app is React/Vue/anything-else, you're embedding it the way you'd embed any other web component or third-party widget.
What it costs to introduce
The integration itself is small enough to get to a working demo in an afternoon. The real engineering cost is what you'd expect from any new extension surface:
- Designing the tool list. This is API design. Treat tools as a public API, because effectively they are.
- Authorisation. Every tool runs in your code. Apply your normal auth checks. Don't assume the call originated from a Rough Feature is somehow safer than a normal API call — assume it isn't.
- Observability. You'll want to log Rough-originated tool calls the way you log other API traffic.
- Schema versioning. When tool shapes change, treat it like changing an API. The Rough management UI will help you see what's depending on what.
What you don't have to build
- A code editor, a UI builder, or a deployment pipeline for user-built features.
- A sandbox runtime, an iframe bridge, or a postMessage protocol.
- A type-generation layer or contract validation.
- A management UI for what's been built and who built it.
- Any AI infrastructure for the natural-language Feature builder.
How to think about the security model
The short version is: tools are your access control. The bridge guarantees a Feature can only invoke tools you've registered, with inputs that match your schema. Anything beyond that is your job — same as for any API consumer.
A more thorough walk-through is on the security page. The architecture is on how RAF works.
A reasonable rollout
- Pick one Surface. Somewhere low-stakes — an internal admin panel is ideal for the first integration.
- Expose a small tool list. Two or three tools is plenty to start.
- Get a Feature built end-to-end and watch it work.
- Expand the tool list and the Surfaces from there as you learn what your users actually try to do.
Related
- How RAF works — the architecture.
- Security — what's enforced and how.
- Features — what your users will actually be building.