Step-by-step delivery
How-To Guides
This section is for practical build sequences: from first publish to production-safe automation, with explicit route and capability boundaries.
Execution-first implementation guides for production Vibecodr work.
Implementation focus
Use this section when you are wiring a feature now and need execution order, expected outcomes, and quick checks.
Expected outcomes
- Ship a new vibe without breaking existing links.
- Move backend responsibilities into Pulses with clear ownership.
- Apply automation and secret rules before exposing public routes.
Step-by-Step Guides
Click a guide to expand it. Each includes code examples you can copy.
Update a Live App with BUMP IT
Free
Ship a new version on the same app listing without losing cut history
Use BUMP IT when an app already has a public player page and you want to ship the next version without creating a second top-level listing.
- Open the live app in Studio from the player manage menu, Settings > Versions, or your launchpad.
- Edit the draft until the new version looks right in preview.
- Choose BUMP IT to publish the next artifact on the same app page.
- Use the Versions tab later if you need a pinned cut or want to revert safely.
BUMP IT keeps the same player page, social graph, and app identity. The only thing that advances is the live Drop pointing at the newest artifact.
Configure Public.pulse Values
Free
Read caller-safe config from env.pulse inside your pulse handler
Use .pulse for public, owner-authored config like default units, destination ids, and feature flags. Keep secrets and tokens in Pulse Secrets instead of .pulse.
.pulse + env.pulse
# .pulse
DEFAULT_UNITS=metric
SUPPORT_QUEUE_NAME=triage
FEATURE_FLAG=true
import { definePulse } from "@vibecodr/pulse";
export default definePulse(async (input, env) => {
return {
city: typeof input?.city === "string" ? input.city : "unknown",
units: env.pulse.DEFAULT_UNITS ?? "metric",
queue: env.pulse.SUPPORT_QUEUE_NAME ?? "general",
featureEnabled: env.pulse.FEATURE_FLAG === "true",
};
});
Use Secrets
Creator+
Call external APIs without exposing your keys
Secrets are private setup capabilities. Start with env.fetch(..., { auth: env.secrets.bearer("KEY") }) so the runtime applies credential policy and your code never handles the plaintext secret.
Recommended: server-side secret injection
Use env.fetch with env.secrets.bearer/header/query and let the runtime attach the credential through a policy-controlled outbound request.
Secret-backed request (recommended)
const response = await env.fetch("https://api.stripe.com/v1/customers", {
method: "POST",
auth: env.secrets.bearer("STRIPE_SECRET_KEY"),
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
email: "user@example.com",
}).toString(),
});
const data = await response.json();
return { customerId: data.id };
How it works: the runtime injects the secret server-side, applies outbound policy checks, and only returns the upstream response. The real secret never appears in your code, logs, or public source.
Alternative: user-connected provider account
If the upstream should run on behalf of a connected user account, use env.connections.use(provider).fetch(...) instead of a shared secret.
Connected account example
const github = env.connections.use("github");
const response = await github.fetch("/user", {
headers: {
Accept: "application/vnd.github+json",
},
});
const profile = await response.json();
return { login: profile.login, id: profile.id };
Add secrets in Studio → Configure → Secrets (or Pulse Operating Center → Secrets). Do not hard-code provider credentials in source; collect the value through a trusted setup form or use the UI.
Set Up Automations
Creator+
Run pulses on a schedule or in response to events
Run a Pulse on a schedule, when webhooks hit, or when your vibe emits a filtered event - no manual clicks needed. For most creators, the friendliest setup is moment → Pulse → Pulse State memory → Recent runs.
Schedule-based
Run your pulse every hour, day, week, or custom interval. Schedules pass a stable scheduled window key for Run once per event.
Webhook-triggered
Get a unique URL to receive webhooks from services like Stripe or GitHub. Verify the webhook, then use runOnce() with the verified event id.
Event-based
React to Vibecodr events like runs or errors. Filter to the smallest event set you need, then let a Pulse use the safe event identity.
Create triggers from the product controls
- Open the Pulse Operating Center for the Pulse.
- Choose the trigger kind: schedule, webhook, event, or manual.
- Configure only the event types, schedule, or signature settings you need.
- Run a test and check Recent runs before relying on the automation.
Receive Webhooks
Creator+
Accept incoming webhooks from external services
Create a Pulse endpoint to receive data from external services, then verify the request before parsing or performing side effects. Stripe has the first full provider helper. Other signed providers use env.secrets.verifyHmac(...) until their own helpers have fixture-backed conformance.
Stripe webhook receiver
import { definePulse } from "@vibecodr/pulse";
export default definePulse(async (_input, env) => {
const event = await env.webhooks.verify("stripe", {
secret: "STRIPE_WEBHOOK_SECRET",
maxBytes: 256 * 1024,
});
env.log.info("stripe.webhook.verified", { type: event.type });
return new Response("ok", { status: 200 });
});
Generic signed webhook receiver
import { definePulse } from "@vibecodr/pulse";
export default definePulse(async (_input, env) => {
const rawBody = await env.request.raw.arrayBuffer({ maxBytes: 256 * 1024 });
const verified = await env.secrets.verifyHmac("GITHUB_WEBHOOK_SECRET", {
format: "github-sha256",
message: rawBody,
signatureHeader: env.request.headers.get("x-hub-signature-256"),
maxBytes: 256 * 1024,
});
if (!verified.ok) return new Response("unauthorized", { status: 401 });
const payload = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(rawBody));
env.log.info("webhook.verified", { action: payload.action ?? "unknown" });
return new Response("ok", { status: 200 });
});
Do not ask the provider-helper layer for GitHub, Shopify, or Slack yet. Use an HMAC format preset for those providers. Put webhook secrets in Studio → Configure → API → Secrets or the Pulse Operating Center.
Configure the webhook URL in the Pulse Operating Center → Automations → Webhooks.
Advanced SQL compatibility
Pro
Use env.db only as an advanced compatibility surface on eligible plans
If you truly need SQL, env.db is available in pulse/combo handlers on eligible plans. Treat it as advanced compatibility rather than the default Pulse backend model, and do not assume automatic Pulse State migration.
Advanced env.db queries
// Query data
const { results } = await env.db.query(
"SELECT * FROM users WHERE active = ?",
[true]
);
// Insert data
await env.db.query(
"INSERT INTO pulse_users (id, name, email) VALUES (?, ?, ?)",
[crypto.randomUUID(), "Alice", "alice@example.com"]
);
// Transaction (batch)
await env.db.batch([
{ sql: "UPDATE accounts SET balance = balance - ? WHERE id = ?", params: [100, fromId] },
{ sql: "UPDATE accounts SET balance = balance + ? WHERE id = ?", params: [100, toId] },
]);
Observability
Free
Debug your pulses and track automation runs
Monitor your pulse executions and automation history.
Pulse logging
Use env.log in your pulse handler for structured logging. Errors are surfaced in execution results.
Logging in a pulse
export default async function handler(input, env) {
env.log.info("start", { inputPreview: JSON.stringify(input).slice(0, 120) });
try {
// ... do work
return {
processed: true,
method: env.request.method,
};
} catch (err) {
env.log.error("error", { message: err instanceof Error ? err.message : String(err) });
throw err;
}
}
Automation executions
View recent runs for any trigger - see status, timing, and error messages.
Each execution includes: id, status (success/partial/failed), firedAt timestamp, and errorMessage when applicable.
First publish path
A safe first publish starts with the smallest working surface. Build or paste the client experience, preview it, add metadata that explains what the viewer can do, then publish only when the runtime output matches the intended behavior.
Publishing creates a public post and an artifact that viewers run. Later updates should use BUMP IT when the same app identity should keep its backlinks, embeds, and discovery history.
- Use Composer for quick ideas and Studio for project-shaped work.
- Preview before publishing so runtime and source assumptions are checked early.
- Add creator SEO fields during publish when the post should be discoverable outside Vibecodr.
- Use BUMP IT for updates to the same app; publish a new app only when the identity should change.
Production-safe Pulse path
When an app needs a backend, create Pulse files under the server lane instead of putting secrets or privileged calls into the vibe. The client calls same-origin /api routes, while the Pulse runs on the trusted edge plane.
The owner is responsible for application-level authorization when a public endpoint should not be open-ended. Vibecodr keeps platform grants and secrets out of public projection, but it does not magically know the business rules for every endpoint.
- Put secret-backed provider calls in Pulses, not browser code.
- Validate request shape and method in the Pulse handler.
- Add signatures, session checks, or rate limits for restricted behavior.
- Keep response payloads minimal and avoid returning secrets or operational metadata.
Example and read next
Example: you imported a small app, previewed it, added SEO copy, confirmed the live runtime, and now need the same public identity to keep moving forward. Use the publish flow first, then BUMP IT for future cuts.
Use these related pages when you need the next layer of guidance. They point to the most likely follow-up tasks, not every page that happens to touch the same system.
- Read next: VibeComposer
- Read next: Studio
- Read next: BUMP IT
- Read next: Pulse Routing