Frontend Launch Kit

Vibe-code a Next.js frontend while SteelEngine runs your deployed backend workflows.

Vibe-code the product experience while SteelEngine handles the backend workflows. The Frontend Launch Kit exports every deployed workflow in a workspace as version-pinned TypeScript fetch functions, cURL examples, React Query mutations, and a secure Next.js proxy that you can drop into an app.

Browser UI → React Query mutation → Next.js server proxy → deployed SteelEngine workflow
Coding agent → SteelEngine MCP → edit, test, and deploy → export a refreshed client

The browser never receives your workspace API key. Deployment IDs remain pinned in server code, so a frontend keeps calling the version it was built and tested against until you deliberately refresh the export.

What the export contains

Choose Export client code once and SteelEngine downloads one ZIP for the workspace. It includes all currently deployed workflows and every available deployment version.

FilePurpose
workflows.tsServer-side fetch functions for every version, plus an alias for the active version at export time
react-query.tsClient-side mutation hooks and stable workflowMutationKeys factories
client.tsServer-only fetch client and typed error class
contracts.tsBrowser-safe input types generated from each workflow's Start block
nextjs/.../route.tsSame-origin proxy that keeps the workspace key private and allowlists exported versions
examples.curl.shReady-to-run request for every deployed version
manifest.jsonWorkflow IDs, deployment IDs, version descriptions, and input inventory
package.json and tsconfig.jsonType checking, cURL, shadcn/ui scripts, and peer requirements
AGENTS.mdInstructions for coding agents working with the generated client and SteelEngine MCP
.env.exampleSTEELENGINE_API_URL plus an intentionally empty WORKSPACE_API_KEY

Generated input types come from the Start block's input format. Give workflows, deployments, and input fields clear descriptions before exporting; those descriptions become useful context for developers and coding agents.

Build the app

Build and test the workflow in SteelEngine. Define the public input contract in the Start block, describe what the workflow and deployment do, and then deploy it.

Deployed versions are immutable snapshots. Draft changes do not affect an app until you create a new deployment and export the client again. Learn more in Execution.

In the workspace sidebar, find Workflows, open More actions (), and choose Export client code. Extract the downloaded ZIP into the root of the frontend repository and name the folder steelengine-client.

my-app/
├── app/ or src/app/
├── steelengine-client/
├── package.json
└── tsconfig.json

If you need a new app, create one first:

npx create-next-app@latest my-app --typescript --tailwind --eslint --app --src-dir
cd my-app

With steelengine-client in the app root, install React Query and initialize every shadcn/ui component with one command:

npm install @tanstack/react-query && npm --prefix steelengine-client run ui:setup

To start with a palette and font system from shadcn/create, use its preset code instead:

npm install @tanstack/react-query && npm --prefix steelengine-client run ui:init -- --preset YOUR_PRESET_CODE && npm --prefix steelengine-client run ui:add-all

For an existing shadcn/ui app, apply only a new theme and fonts:

npm --prefix steelengine-client run ui:apply -- --preset YOUR_PRESET_CODE --only theme,font

Copy the example into the Next.js environment file:

cp steelengine-client/.env.example .env.local

Create a workspace execution key under Workspace Settings → API Keys, then complete the file:

STEELENGINE_API_URL="https://YOUR_STEELENGINE_HOST"
WORKSPACE_API_KEY="YOUR_WORKSPACE_API_KEY"

Never prefix the key with NEXT_PUBLIC_ or expose it through browser code. The generated React Query hooks call your own Next.js route, not SteelEngine directly.

Copy the generated route into the matching App Router location:

steelengine-client/nextjs/app/api/steelengine/workflows/[workflowId]/execute/route.ts
→ src/app/api/steelengine/workflows/[workflowId]/execute/route.ts

Omit src/ when the app uses a root-level app/ directory. Keep the generated deployment map on the server; it prevents a browser from requesting an arbitrary workflow or version.

Keep the generated folder replaceable by importing it through an alias. Merge this path into the app's tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"],
      "@steelengine-client/*": ["./steelengine-client/*"]
    }
  }
}

If the app does not use src/, keep its existing @/* value and add only the @steelengine-client/* entry.

Create one client provider with a stable QueryClient:

// src/app/providers.tsx
'use client'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState, type ReactNode } from 'react'

export function Providers({ children }: { children: ReactNode }) {
  const [queryClient] = useState(() => new QueryClient())

  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}

Render it once from the root layout:

// src/app/layout.tsx
import type { ReactNode } from 'react'
import { Providers } from './providers'

export default function RootLayout({ children }: Readonly<{ children: ReactNode }>) {
  return (
    <html lang="en">
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}

Generated browser hooks are mutations because workflow execution uses POST and can have side effects. Import the active-version alias shown in react-query.ts:

'use client'

import { useCustomerSummary } from '@steelengine-client/react-query'
import { Button } from '@/components/ui/button'

export function RunCustomerSummaryButton({ accountId }: { accountId: string }) {
  const summary = useCustomerSummary()

  return (
    <Button
      disabled={summary.isPending}
      onClick={() => summary.mutate({ accountId })}
    >
      {summary.isPending ? 'Building summary…' : 'Build summary'}
    </Button>
  )
}

The names and inputs depend on the exported workflows. Use mutateAsync when subsequent UI logic needs the result, and invalidate app-owned query keys in onSuccess when the workflow changes data displayed elsewhere.

Run the generated type check from the application root:

npm --prefix steelengine-client run check

You can also inspect manifest.json, use the version comments in workflows.ts, or test the requests from a shell with npm --prefix steelengine-client run curl:examples. The cURL command executes the workflows, so use test inputs and a non-production workspace when appropriate.

Vibe-code safely with SteelEngine MCP

The exported AGENTS.md tells a coding agent how this folder works and where custom application code belongs. It also separates the two SteelEngine surfaces:

  • Execution data plane: the generated REST client calls immutable deployed workflow versions.
  • Management control plane: SteelEngine MCP lets an authorized agent inspect, edit, test, deploy, and manage workflows through the steelengine_workflows tool.

When the UI needs a different workflow input or behavior:

  1. Ask the coding agent to inspect the consuming component and manifest.json.
  2. Connect the agent to /api/mcp/steelengine if SteelEngine MCP is not already available.
  3. Authenticate with OAuth or a dedicated SteelEngine MCP API key sent in X-API-Key.
  4. Let the agent update and test the workflow, then deploy a new immutable version.
  5. Export the client again, replace steelengine-client, run its check, and update the UI.

A SteelEngine MCP key and WORKSPACE_API_KEY serve different purposes. Keep both out of browser code, grant the MCP key only the permissions the agent needs, and treat call-time permission denials as authoritative.

Server Components and backend jobs

Client components should use react-query.ts. Server Components, Route Handlers, Server Actions, and backend jobs can call the versioned functions from workflows.ts directly:

import { runCustomerSummaryV2 } from '@steelengine-client/workflows'

const summary = await runCustomerSummaryV2({ accountId: 'account_123' })

The version suffix is the strongest reproducibility guarantee. The unsuffixed alias is convenient, but it is only the active deployment at the moment the ZIP was created—it does not silently follow future deployments.

Where to go next

On this page