Form Builder

Build stylish, Typeform-like multi-step forms and surveys using the Rebyte Forms library (Composer API). Outputs standalone HTML files. Triggers include "create a form", "build a survey", "make a questionnaire", "feedback form", "contact form", "signup form", "onboarding flow", "multi-step form", "typeform-style", "data collection form". Do NOT use for simple single-field inputs or backend form processing.

Published by rebyteai

Featured Design

Cloud-native skill

Runs in the cloud

No local installation

Dependencies pre-installed

Ready to run instantly

Secure VM environment

Isolated per task

Works on any device

Desktop, tablet, or phone

Documentation

Rebyte Forms Builder

Build production-ready, Typeform-style forms using the Composer API.

For Non-Technical Users

IMPORTANT: This skill is designed for non-technical users.

  • DO NOT explain commands or show bash/terminal syntax to the user
  • DO NOT ask the user to run commands themselves
  • DO NOT give technical instructions like "run this command"
  • JUST EXECUTE and show results directly
  • Keep responses focused on outcomes, not technical steps

Common Mistakes to Avoid

  • Showing dev server output: Never show "localhost:3000" or similar - the user can't access it and doesn't care
  • Running npm run dev: Don't start dev servers and show the output. Export/build instead.
  • Explaining installation steps: Just install dependencies silently
  • Showing terminal output: Unless it's an error you need to debug, hide it
  • Asking "should I run X?": Just run it

⚠️ CRITICAL: Completion Requirements

A form task is NOT complete until:

  1. ✅ Form backend created (POST /api/forms/create)
  2. ✅ HTML file saved as index.html
  3. Invoke the rebyte-app-builder skill to deploy the form
  4. ✅ BOTH URLs shared with user: Form URL (from deployment) AND Admin URL (from form creation API)

NEVER tell the user the form is "done" without completing ALL steps.

Authentication

IMPORTANT: All API requests require authentication. Get your auth token and API URL by running:

AUTH_TOKEN=$(/home/user/.local/bin/rebyte-auth)
API_URL=$(python3 -c "import json; print(json.load(open('/home/user/.rebyte.ai/auth.json'))['sandbox']['relay_url'])")

Include the token in all API requests as a Bearer token, and use $API_URL as the base for all API endpoints.

Artifact Store

If this skill produces output files (PDFs, images, exports, etc.), you MUST upload them to the artifact store. Without this, users cannot access the files - they only exist inside the VM.

Upload whenever you generate:

  • Exported documents (PDF, Word, Excel, PowerPoint)
  • Images (screenshots, generated graphics, charts)
  • Media files (videos, audio)
  • Any file the user asked to "download" or "export"
curl -X PUT "$API_URL/api/artifacts" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -F "files=@/path/to/file.pdf"

Multiple files:

curl -X PUT "$API_URL/api/artifacts" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -F "files=@file1.png" \
  -F "files=@file2.png"

Allowed file types:

  • Documents: .pdf, .doc(x), .xls(x), .ppt(x), .csv, .tsv, .rtf, .epub, .html
  • Archives: .zip, .tar, .gz, .tgz
  • Images: .png, .jpg, .gif, .webp, .svg, .tiff, .bmp, .avif
  • Videos: .mp4, .webm, .mov, .avi, .mkv
  • Audio: .mp3, .wav, .ogg, .aac, .flac, .m4a

Not allowed: Source code, config files, or development files.

Boilerplate Template

<!DOCTYPE html>
<html lang="en" spellcheck="false" class="fmd-root" data-fmd-color-scheme="light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{TITLE}}</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/rebyte-forms@1.0.1/dist/css/formsmd.min.css">
</head>
<body class="fmd-body">
    <noscript>Please turn on JavaScript to see this page.</noscript>
    <div class="fmd-main">
        <div class="fmd-main-container">
            <div class="fmd-loader-container">
                <div class="fmd-loader-spinner" role="status" aria-label="Loading"></div>
            </div>
        </div>
    </div>

    <script src="https://unpkg.com/rebyte-forms@1.0.1/dist/js/composer.bundle.min.js"></script>
    <script src="https://unpkg.com/rebyte-forms@1.0.1/dist/js/formsmd.bundle.min.js"></script>
    <script>
        const composer = new Composer({
            title: "{{TITLE}}",
            colorScheme: "light",
            accent: "#6366f1",
            accentForeground: "#ffffff",
            backgroundColor: "#fafafa",
            color: "#18181b",
            fontFamily: "Inter, sans-serif",
            pageProgress: "show",
        });

        // Start slide
        composer.startSlide({ buttonText: "Get Started" });
        composer.h1("Welcome");
        composer.p("Introduction text here.");

        // Form slides go here...

        // End slide
        composer.endSlide();
        composer.h1("Thank you!");
        composer.p("Your response has been recorded.");

        // Initialize
        const formsmd = new Formsmd(composer.template, document, { isFullPage: true });
        formsmd.init();
    </script>
</body>
</html>

Composer Settings

Setting Type Description
title string Page title
colorScheme "light" | "dark" Default color scheme
accent string Primary color (hex) for buttons, fields
accentForeground string Text color on accent background
backgroundColor string Page background color
color string Text color
backgroundImage string CSS background-image (gradient or url)
backdropOpacity string Overlay opacity on background image (e.g., "0.4")
fontFamily string Font family
fontSize "sm" | "lg" Font size
rounded "none" | "pill" Button/UI rounding
pageProgress "hide" | "show" | "decorative" Progress bar style
formStyle "classic" Classic form field appearance
postUrl string URL to POST form responses

Field Types

Text Input

composer.textInput("fieldName", {
    question: "What's your name?",
    placeholder: "John Doe",
    required: true,
    description: "Optional helper text",
    multiline: true,  // for textarea
    maxlength: 500,
    autofocus: true,
    subfield: true,   // smaller label (for grouping)
});

Email Input

composer.emailInput("email", {
    question: "Your email address?",
    placeholder: "you@example.com",
    required: true,
});

Phone Input

composer.telInput("phone", {
    question: "Phone Number",
    country: "US",  // default country code
    required: true,
});

URL Input

composer.urlInput("website", {
    question: "Your website",
    placeholder: "https://example.com",
});

Number Input

composer.numberInput("salary", {
    question: "Expected salary (USD)",
    placeholder: "100000",
    unit: "$",
    min: 50000,
    max: 500000,
});

Choice Input (Radio/Checkbox)

// Simple choices
composer.choiceInput("role", {
    question: "What's your role?",
    choices: ["Developer", "Designer", "Manager", "Other"],
    required: true,
});

// With custom values
composer.choiceInput("ticket", {
    question: "Select ticket type",
    choices: [
        { label: "General - $99", value: "general" },
        { label: "VIP - $299", value: "vip" },
    ],
    required: true,
});

// Multiple selection
composer.choiceInput("skills", {
    question: "Select your skills",
    description: "Choose all that apply",
    choices: ["JavaScript", "Python", "Go", "Rust"],
    multiple: true,
});

// Horizontal layout
composer.choiceInput("size", {
    question: "T-Shirt Size",
    choices: ["S", "M", "L", "XL"],
    horizontal: true,
});

Select Box (Dropdown)

composer.selectBox("country", {
    question: "Select your country",
    placeholder: "Choose one",
    options: ["USA", "Canada", "UK", "Germany", "Other"],
});

Rating Input

composer.ratingInput("satisfaction", {
    question: "How satisfied are you?",
    outOf: 5,
    icon: "star",
    required: true,
});

Opinion Scale (NPS)

composer.opinionScale("nps", {
    question: "How likely are you to recommend us?",
    startAt: 0,
    outOf: 10,
    labelStart: "Not likely",
    labelEnd: "Very likely",
    required: true,
});

File Upload

composer.fileInput("resume", {
    question: "Upload your resume",
    description: "PDF format, max 10MB",
    sizeLimit: 10,
    required: true,
});

Date/Time Inputs

composer.dateInput("startDate", { question: "Start date" });
composer.timeInput("preferredTime", { question: "Preferred time" });
composer.datetimeInput("appointment", { question: "Select date and time" });

Slide Structure

// Start slide (intro)
composer.startSlide({ buttonText: "Begin" });
composer.h1("Title");
composer.p("Description");

// Regular slide
composer.slide();
composer.textInput("name", { question: "Your name?", required: true });

// Another slide with multiple fields
composer.slide();
composer.h2("Contact Details");
composer.emailInput("email", { question: "Email", required: true });
composer.telInput("phone", { question: "Phone", subfield: true });

// End slide
composer.endSlide();
composer.h1("Thanks!");

Conditional Display

Show a field only when a condition is met:

composer.choiceInput("wantFollowUp", {
    question: "Can we follow up?",
    choices: [
        { label: "Yes", value: "yes" },
        { label: "No", value: "no" },
    ],
});

composer.emailInput("followUpEmail", {
    question: "Your email for follow-up",
    displayCondition: {
        dependencies: ["wantFollowUp"],
        condition: "wantFollowUp == 'yes'",
    },
});

Theme Presets

Light Professional

const composer = new Composer({
    colorScheme: "light",
    accent: "#18181b",
    accentForeground: "#fafafa",
    backgroundColor: "#fafafa",
    color: "#18181b",
    fontFamily: "DM Sans, sans-serif",
    formStyle: "classic",
    pageProgress: "show",
});

Dark Modern

const composer = new Composer({
    colorScheme: "dark",
    accent: "#a855f7",
    accentForeground: "#ffffff",
    backgroundColor: "#0f0a1e",
    color: "#e2e8f0",
    backgroundImage: "linear-gradient(135deg, #1a0a2e 0%, #16213e 50%, #0f0a1e 100%)",
    fontFamily: "Space Grotesk, sans-serif",
    rounded: "pill",
    pageProgress: "show",
});

Warm Feedback

const composer = new Composer({
    colorScheme: "light",
    accent: "#f97316",
    accentForeground: "#ffffff",
    backgroundColor: "#fffbeb",
    color: "#451a03",
    backgroundImage: "linear-gradient(180deg, #fef3c7 0%, #fffbeb 50%, #fff7ed 100%)",
    fontFamily: "Outfit, sans-serif",
    fontSize: "lg",
    pageProgress: "show",
});

With Background Image

const composer = new Composer({
    colorScheme: "dark",
    accent: "#f472b6",
    accentForeground: "#ffffff",
    backgroundColor: "#1e1b4b",
    color: "#f8fafc",
    backgroundImage: "url('https://images.unsplash.com/photo-xxx?w=1920&q=80')",
    backdropOpacity: "0.4",
    fontFamily: "Plus Jakarta Sans, sans-serif",
    rounded: "pill",
});

Collecting Form Submissions

To collect responses, you need to:

  1. Create a form backend (stores submissions)
  2. Add postUrl to your HTML form
  3. Save HTML as index.html
  4. Invoke the rebyte-app-builder skill to deploy

Complete Workflow

Step 1: Create Form Backend

Call the Forms API to create a backend that stores submissions:

curl -X POST "$API_URL/api/forms/create" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My Survey",
    "fields": ["name", "email", "rating", "feedback"]
  }'

IMPORTANT: The fields array must contain the exact field names you use in your form (e.g., composer.textInput("name", ...) means "name" goes in fields).

Response:

{
  "formId": "abc123def456",
  "submitUrl": "https://.../api/forms/submit/abc123def456",
  "adminUrl": "https://.../forms/abc123def456",
  "fields": ["name", "email", "rating", "feedback"]
}

Save these URLs:

  • submitUrl: Where form data is POSTed (use as postUrl in Composer)
  • adminUrl: Spreadsheet UI to view all submissions (share with form creator)

Step 2: Configure Form HTML

Add the submitUrl as postUrl in your Composer settings:

const composer = new Composer({
    title: "My Survey",
    postUrl: "<submitUrl from API response>",
    // ... other settings
});

Step 3: Save and Deploy

  1. Save the form HTML as index.html
  2. Invoke the rebyte-app-builder skill to deploy it
  3. The skill will handle ZIP creation, upload, and deployment

Final URLs to Share

After deployment, you'll have:

  • Form URL: From the rebyte-app-builder skill output - Share with respondents
  • Admin URL: From the form creation API response (Step 1) - View responses in spreadsheet

Viewing Results

Admin UI (Recommended): Open adminUrl in a browser to view responses in a spreadsheet interface with CSV/JSON export.

API Endpoints (for programmatic access):

  • JSON: GET $API_URL/api/forms/results/{formId}
  • CSV: GET $API_URL/api/forms/results/{formId}/csv

IMPORTANT: Always Return Both URLs

When you finish building and deploying a form, you MUST tell the user both URLs:

  1. Form URL (for respondents): From the rebyte-app-builder skill output
  2. Admin URL (for viewing results): From the form creation API response (Step 1)

Never forget the Admin URL - without it, the user cannot see their form submissions!

Skill as a Service

Everyone else asks you to install skills locally. On Rebyte, just click Run. Works from any device — even your phone. No CLI, no terminal, no configuration.

  • Zero setup required
  • Run from any device, including mobile
  • Results streamed in real-time
  • Runs while you sleep
Run this skill now

Compatible agents

Claude Code

Gemini CLI

Codex

Cursor, Windsurf, Amp

rebyte.ai — The only platform where you can run AI agent skills directly in the cloud

No downloads. No configuration. Just sign in and start using AI skills immediately.

Use this skill in Agent Computer — your shared cloud desktop with all skills pre-installed. Join Moltbook to connect with other teams.