Required first step when creating any new project. Call createArtifact() to scaffold a runnable project (web app, video, slides, mobile).
An artifact is a runnable project that the agent creates for the user. It is the primary unit of output the agent delivers.
Each artifact is a workspace package under artifacts/<slug>/ in the monorepo. Calling createArtifact() runs the shared bootstrap flow for the chosen artifact type, scaffolds the project files, installs dependencies, writes an artifact.toml with metadata, allocates service ports, and wires the artifact into .replit so it can be previewed and deployed.
When the user asks you to "build a website" or "create an app", you are creating an artifact. Call createArtifact() once, then continue implementation.
The workspace already includes a shared backend service. New web artifacts are primarily frontend packages and must treat previewPath as a required URL prefix for all app routes and API calls.
Use this skill when:
<!-- BEGIN_ARTIFACT_LIST --> <!-- END_ARTIFACT_LIST --> <!-- BEGIN_SERVICES_TABLE --> <!-- END_SERVICES_TABLE --> <!-- BEGIN_EXAMPLES --> <!-- END_EXAMPLES --> <!-- BEGIN_BOOTSTRAP_CONSTRAINTS --> <!-- END_BOOTSTRAP_CONSTRAINTS -->Add work to an existing artifact when it is a feature, page, or component of that artifact's product and shares the same domain, branding, and purpose.
Create a new artifact when the work is for a different product or domain, has different branding or purpose, or the user used standalone language like "make a web app" or "create a component." Do not reuse an existing artifact just because it is convenient.
Not everything needs an artifact. If the output is a file asset (script, document, image, CSV, config file, etc.), just create the file directly and tell the user where it is. Artifacts are for runnable projects with a preview, not for standalone files.
If ambiguous, ask the user: "Should I create this as a new standalone web app, or add it to [existing artifact name]?"
createArtifactcreateArtifact twice for the same slug)Not all artifacts follow the same workflow. Choose your approach based on the artifact type:
mockup-sandbox skill. It uses its own Vite dev server and canvas iframes. Delegate design work to a DESIGN subagent. No artifact is needed if the mockup sandbox is present.slides skill — no subagent is needed. Use media-generation for images.video-js skill. Always delegate the entire build to a DESIGN subagent — do not build the video yourself.react-vite artifact is frontend-only and does not need a backend, skip the OpenAPI spec and codegen steps — go straight to building the frontend after calling createArtifact().Full-stack artifacts — OpenAPI-first workflow:
Get async work running as early as possible so it can proceed in the background while you build.
createArtifact(). It will guide you to the artifact's skill for build instructions.lib/api-spec/openapi.yaml — this is the single source of truth for all API contracts. It is on the critical path: the spec gates codegen, which gates the frontend.pnpm run --filter @workspace/api-spec codegen) — generates React Query hooks and Zod schemas. Do NOT read the generated files; they are large and will fill your context.generateFrontend() for react-vite, design subagent for others). Do NOT do any other work between codegen and launching the frontend build.Key principles:
Artifact creation is a single callback call. createArtifact() handles bootstrap + registration internally.
const result = await createArtifact({
artifactType: "<artifactType>",
slug: "<slug>",
previewPath: "/",
title: "My Project"
});
createArtifact() expects a fresh slug. If artifacts/<slug>/ already exists, the call fails instead of trying to reuse partially created files.
Bootstrap and register a new artifact in one call. This should be your default for all new artifacts, and it requires an unused slug.
Parameters:
artifactType (str, required): The artifact type identifier. Use one of:
"expo" (mobile app)"data-visualization" (data visualization scaffold (dashboards, analysis reports, dataset explorers) with chart/table defaults)"mockup-sandbox" (isolated mockup sandbox for rapid UI prototyping on the canvas)"react-vite" (React + Vite web app)"slides" (presentation slide deck scaffold)"video-js" (Replit Animation app)slug (str, required): A short, kebab-case slug (e.g., "my-website", "q1-pitch-deck", "budget-tracker"). This slug is used in two places:
@workspace/<slug>artifacts/<slug>/previewPath (str, required): The URL prefix where the artifact is served. Use "/<slug>/" (e.g., "/my-website/", "/budget-tracker/") for consistency. However, one artifact should always be at "/" — if nothing is at the root, the dev URL (e.g. my-app.replit.app) shows a blank page, which is a bad experience. Prefer placing web apps (react-vite, data-visualization) at the root over mobile, video, or slides artifacts. Every artifact in the workspace must use unique service paths.title (str, required): A short, human-readable title for the artifact (e.g., "Recipe Finder", "Q1 Pitch Deck"). Displayed to the user in the UI.Returns: Dict with:
success (bool): Whether the operation succeededartifactId (str): The stable artifact ID — pass this to presentArtifactports (dict[str, int]): Map of service names to their assigned local portsExample:
const result = await createArtifact({
artifactType: "react-vite",
slug: "my-website",
previewPath: "/",
title: "Recipe Finder"
});
List all artifacts currently registered in the workspace. Use this to look up artifact IDs when you need to present or reference an artifact you didn't just create.
Parameters: None
Returns: Dict with:
artifacts (list): Each entry contains:
artifactId (str): The stable artifact ID — pass this to presentArtifactkind (str): How the artifact is presented (preview kind, e.g., "web", "slides", "video")title (str | null): The human-readable titleartifactDir (str): The folder name where the artifact livesExample:
const {artifacts} = await listArtifacts();
presentArtifact + suggestDeployAfter building the artifact, present it and — for deployable types — suggest publish, all in one code execution block.
Deployable artifacts (react-vite, expo, data-visualization) — present and suggest deploy:
await presentArtifact({artifactId: result.artifactId});
await suggestDeploy();
Non-deployable artifacts (slides, video-js, mockup-sandbox) — present only. mockup-sandbox is a local prototyping sandbox and is not meant to be deployed. slides and video-js are exported from the preview pane. Never call suggestDeploy for these types:
await presentArtifact({artifactId: result.artifactId});
presentArtifact opens the preview pane so the user can see what you built. Without this call, the user won't see the artifact preview — even if the app is running correctly. Pass the artifactId (str, required) returned by createArtifact.suggestDeploy prompts the user to publish their project with one click. Takes no parameters. This is a terminal action — once called, do not take further actions.Always call presentArtifact after finishing work on any artifact — whether you just created it, made changes to it, or fixed a bug in it. If you built multiple artifacts, present each one. Some skills define additional post-present steps (e.g., data analysis); follow those skill-specific instructions after presenting.
| Artifact | Preview Kind | Service name(s) | Dev command(s) | Path | Production serve | Production build | Production run |
|---|---|---|---|---|---|---|---|
expo | mobile | expo | pnpm --filter @workspace/__SLUG__ run dev | previewPath | pnpm --filter @workspace/__SLUG__ run build | pnpm --filter @workspace/__SLUG__ run serve | |
data-visualization | web | web | pnpm --filter @workspace/__SLUG__ run dev | previewPath | static | pnpm --filter @workspace/__SLUG__ run build | |
mockup-sandbox | design | web | pnpm --filter @workspace/__SLUG__ run dev | previewPath | — | — | — |
react-vite | web | web | pnpm --filter @workspace/__SLUG__ run dev | previewPath | static | pnpm --filter @workspace/__SLUG__ run build | |
slides | slides | web | pnpm --filter @workspace/__SLUG__ run dev | previewPath | static | pnpm --filter @workspace/__SLUG__ run build | |
video-js | video | web | pnpm --filter @workspace/__SLUG__ run dev | previewPath | static | pnpm --filter @workspace/__SLUG__ run build |
The web service's URL prefix is set to whatever you pass as previewPath. Route handling is prefix-aware: frontend routes and API requests must include this prefix.
Mobile: Expo is served directly at its assigned port. The backend is served at {previewPath_without_trailing_slash}-backend/ (deterministic suffix to avoid overlap with the Expo route).
If createArtifact fails, inspect the error and retry with corrected inputs. The callback requires a clean slug on each attempt, so remove any partial artifacts/<slug>/ directory before reusing that slug.
slug, or remove the existing artifact directory before retryingDUPLICATE_PREVIEW_PATH → Choose a different previewPathfiles/ → Migrate that artifact type to the shared bootstrap layout before using createArtifactexpo)const result = await createArtifact({
artifactType: "expo",
slug: "my-app",
previewPath: "/",
title: "My App"
});
const expoPort = result.ports.expo;
// Expo is scaffolded under artifacts/my-app
// and API work should be added to the shared api-server.
await startAsyncSubagent({
task: "Build the mobile app",
fromPlan: true,
relevantFiles: [
".local/skills/expo/SKILL.md",
"artifacts/my-app/app/_layout.tsx",
"artifacts/my-app/app/(tabs)/_layout.tsx",
"artifacts/my-app/app/(tabs)/index.tsx",
"artifacts/api-server/src/index.ts",
"artifacts/my-app/constants/colors.ts"
]
});
await presentArtifact({artifactId: result.artifactId});
await suggestDeploy();
data-visualization)const result = await createArtifact({
artifactType: "data-visualization",
slug: "sales-dashboard",
previewPath: "/sales-dashboard/",
title: "Sales Dashboard"
});
// Recharts, PapaParse, and TanStack React Table are pre-configured
await startAsyncSubagent({
task: "Build the dashboard",
fromPlan: true,
relevantFiles: [
".local/skills/data-visualization/SKILL.md",
"artifacts/dashboard/client/src/pages/Dashboard.tsx",
"artifacts/dashboard/server/routes.ts",
"artifacts/dashboard/client/src/config.ts"
]
});
await presentArtifact({artifactId: result.artifactId});
await suggestDeploy();
Creates a data visualization dashboard with Recharts (charts), PapaParse (CSV parsing), and TanStack React Table (data tables) pre-configured.
Each artifact must have a unique slug and previewPath. At least one artifact MUST use previewPath: "/" — otherwise users will see a blank page at the root.
IMPORTANT: When building multiple artifacts, you MUST read the file references/multi-artifact-creation.md BEFORE creating any artifacts. Do not skip this — it contains critical sequencing and parallelism rules that will significantly affect build quality and speed.
slug can only be used once — calling createArtifact again with the same slug will failartifact: "expo")artifacts/api-server.files/package.json.template so pnpm install produces a runnable app.