Use for fullstack web apps built with the bundled Express, Vite, React, Tailwind, and Drizzle template.
beeuni marketplace install beeuni-starter:webappcp -r skills/webapp/template/ <project-name>/
cd <project-name>
npm install
npm run dev
shared/schema.ts firstserver/routes.tslocalStorage, sessionStorage, indexedDB, or cookies — they are blocked in the sandboxed iframe and will crash the page. Use React state or context for transient data, and the backend API + in-memory storage for persistent data.red Placeholders in index.cssindex.css ships with red placeholder values that must be replaced before the app looks right. Infer a palette from the subject matter first — a fitness tracker should feel energetic (bright accent, dark surfaces), a recipe app should feel warm (amber/terracotta tones), a finance dashboard should feel precise (cool neutrals, blue accent). Derive colors from the product's domain, not from a generic default.H S% L% format (no hsl() wrapper) and maintain both :root and .dark variants following the same variable structure in index.css.skills/website-building/shared/01-design-tokens.md and use a single accent color only where emphasis is needed.text-xl is the max heading size. Web apps (SaaS, dashboards, admin, e-commerce) never use text-2xl or above. Exception: brand experience marketing/landing hero sections — see Art Direction table below.--font-display and --font-body. In this Tailwind template, both map to font-sans — use bold/semibold weight for display territory, regular weight for body territory.| Product Type | Concept-Driven Direction | Token Starting Points |
|---|---|---|
| SaaS / productivity | A writing tool is calm and typographic. A project management tool is structured and efficient. A design tool is visual and spacious. Match personality to purpose. | Neutral surfaces. 1 accent. Body font that matches the product's character. |
| Dashboard / analytics | Finance dashboards demand precision and sobriety. Marketing dashboards can be warmer and more visual. The data's domain sets the tone. | Sans-serif + monospace for data. High-contrast. Load skills/webapp/dashboards.md. |
| E-commerce | Luxury goods: muted surfaces, serif display, restrained accent. Kids' toys: warm, bright, rounded. Outdoor gear: earthy tones, rugged sans-serif. | Warm palette derived from product category. Strong CTA contrast. |
| Brand experience | A music streaming brand differs from an architecture studio. Derive everything from the brand. | Display font at --text-xl in-app; --text-2xl ONLY for marketing/landing hero sections. 1-2 custom accent hues. Theatrical motion. |
| Admin panel | Utilitarian, clear, efficient. A healthcare admin panel feels different from a developer tools panel. | Inter or DM Sans (loaded via CDN, not system fonts). Functional color only. Dense layout. |
shared/schema.ts to ensure consistency between frontend and backend. Do this before writing any other code.createInsertSchema from drizzle-zod. Use .omit to exclude any auto-generated fields.z.infer<typeof insertSchema>typeof table.$inferSelect..array() as a method on the column type, not as a wrapper function. That is, do text().array() instead of array(text()).IStorage in server/storage.ts to accommodate any storage CRUD operations you need in the application.@shared/schema.ts.registerRoutes(httpServer, app) in server/routes.ts. The app parameter is the Express instance — use app.get(), app.post(), etc. to define routes.drizzle-zod before passing it to the storage interface.server/index.ts already sets up Express and calls registerRoutes.useHashLocation from wouter/use-hash-location in your Router and App.tsx. When writing or rewriting App.tsx, always include import { useHashLocation } from "wouter/use-hash-location" and pass hook={useHashLocation} to the Router component. Without this, all routing will break after deployment because sites are served inside iframes where path-based routing breaks.
/#/, /#/tasks, /#/boats/:id<Link href="/tasks"> — wouter handles the hash prefix automatically when useHashLocation is the router hook.client/src/pages directory and register them in client/src/App.tsx.Link component or the useLocation hook from wouter instead of modifying the window directly.href="#section" anchor links for in-page navigation — hash routing intercepts these as route changes, causing a "not found" error. Instead, use onClick handlers with document.getElementById('section')?.scrollIntoView({ behavior: 'smooth' }) to scroll to sections within the same page.useForm hook and Form component from @/components/ui/form which wraps react-hook-form.
zodResolver from @hookform/resolvers/zod to validate the form data using the appropriate insert schema from @shared/schema.ts..extend to add validation rules to the insert schema.useForm hook.@tanstack/react-query when fetching data.
@shared/schema.ts.API_BASE for deployment). If you must write a custom queryFn (e.g., for response parsing or query params), use apiRequest from @/lib/queryClient — NEVER use raw fetch(). Raw fetch() bypasses __PORT_5000__ URL rewriting and API calls will 404 after deployment.apiRequest from @/lib/queryClient for ALL HTTP requests to the backend (GET, POST, PATCH, DELETE) — both in queries and mutations.
queryClient from @lib/queryClient!/api/recipes/${id}]..isLoading) or mutations (via .isPending) are being madeuseQuery({ queryKey: ['key'] }) instead of useQuery(['key'])useToast hook is exported from @/hooks/use-toast.form.formState.errors to see if there are form validation errors for fields that might not have associated form fields.import.meta.env.<ENV_VAR> to access environment variables on the frontend instead of process.env.<ENV_VAR>. Note that variables must be prefixed with VITE_ in order for the env vars to be available on the frontend.data-testid attribute to every HTML element that users can interact with (buttons, inputs, links, etc.) and to elements displaying meaningful information (user data, status messages, dynamic content, key values).
{action}-{target} (e.g., button-submit, input-email, link-profile){type}-{content} (e.g., text-username, img-avatar, status-payment){type}-{description}-{id}
card-product-${productId}, row-user-${index}, text-price-${itemId}@tailwind base; @tailwind components; @tailwind utilities; directives in CSS. Do NOT use @import "tailwindcss" or @theme syntax — those are v4 and will crash the dev server.index.css that will be used by a tailwind config, always use H S% L% (space separated with percentages after Saturation and Lightness) (and do not wrap in hsl()).
index.css to determine how to set colors — replacing every red placeholder. Infer a palette from the product's subject matter first (see "Replacing red Placeholders" above). Use Beeuni HSL values from skills/website-building/shared/01-design-tokens.md only as a last-resort fallback when both inference and asking the user yield no direction. Do NOT forget to replace every single instance of red. Pay attention to what you see in index.css.@-prefixed paths to import shadcn components and hooks.lucide-react to signify actions and provide visual cues. Use react-icons/si for company logos.@assets/... import syntax.attached_assets/example.png, you can reference it in the frontend with import examplePngPath from "@assets/example.png".darkMode: ["class"] in tailwind.config.ts and define color variables in :root and .dark CSS classesuseState seeded from window.matchMedia("(prefers-color-scheme: dark)"), and a useEffect to toggle the "dark" class on document.documentElement. Do not use localStorage or cookies for theme persistence — they are blocked in the sandboxed iframe.tailwind.config.ts, always use explicit light/dark variants for ALL visual properties: className="bg-white dark:bg-black text-black dark:text-white". When using utility classes configured in tailwind config, you can assume these already been configured to automatically adapt to dark mode.npm run dev to start the development server. This starts Express for the backend and Vite for the frontend on the same port. After making edits, the server will automatically reload.npm install <package-name>.skills/website-building/shared/12-playwright-interactive.md for testing and QA. Use Playwright via agent-browser to navigate, interact with, and screenshot your local dev server.cd <project-name>
npm run build
python3 -m http.server 3000 from the output directory, or use the repo's actual deployment command if one exists.npm run buildnode dist/index.cjs via pty_spawn when you need a production-style verification pass.beeuni apps ls exits 0): deploy with the beeuni-apps
system skill (beeuni system-skills get beeuni-apps), only after the user asks
to publish.npm run build, then
beeuni apps deploy dist/public --type static --spa. No machine, no
compute cost.--type dockerfile --on-demand --command '["node","dist/index.cjs"]' --port 5000. In-memory storage is lost whenever the App stops (an on-demand
App stops after 5 idle minutes) and on every new deployment. Say so before
you publish.server/vite.ts and vite.config.ts) unless absolutely necessary. It is already configured to serve the frontend and backend on the same port and handles all the necessary setup for you. Don't add a proxy to the Vite server. All the aliases are already set up for you to import.drizzle.config.ts unless absolutely necessary. It is pre-configured correctly.skills/webapp/references/environment.md — pre-installed packages, dev server setup, deployment constraints.skills/webapp/references/environment.md.website-building dependency and live under skills/website-building/shared/ — NOT under skills/webapp/shared/.skills/website-building/shared/01-design-tokens.md — Always read. Type scale, spacing system, Beeuni palette, base stylesheet. Provides the fallback design system when the user gives no art direction.skills/website-building/shared/02-typography.md — Always read. Font selection (Fontshare preferred), display vs. body rules, font blacklist, variable font features.skills/website-building/shared/03-motion.md — Read when the app has animation. Easing blueprint (which curve for which context), duration quick-reference, spring presets, scroll-driven CLS rules, AnimatePresence patterns. The webapp elevation system for hover/active states is noted inside — the rest of the guidance (easing curves, timing, page transitions, stagger patterns) applies fully.skills/website-building/shared/05-taste.md — Read for any user-facing app. Design taste principles: simplicity, fluidity, feedback, restraint. Defines the "feel" quality bar — progressive disclosure, context-preserving overlays, micro-interactions.skills/website-building/shared/08-standards.md — Always read. Accessibility (WCAG AA, semantic HTML, keyboard nav), performance baselines, and AI aesthetic anti-patterns to avoid.skills/webapp/references/.references/shadcn_component_rules.md - Use when building or modifying UI with Shadcn components (especially Button, Card, Badge, Avatar, and Textarea).references/layout_and_spacing.md - Use when structuring page layouts, sections, spacing rhythm, and component alignment.references/sidebar_rules.md - Use when building or modifying a sidebar.references/visual_style_and_contrast.md - Use when choosing contrast, borders, shadows, pane/panel treatment, and hero image presentation.Get a complete picture of any company or person before outreach. This skill always works with web search, and gets significantly better with enrichment and CRM data.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
Route code, repository, and data/SQL work to isolated Beeuni sessions instead of burning your main context on it. Use when asked to implement a feature, fix a bug, make failing tests pass, work a ticket/issue, refactor, navigate or change a codebase, ship a PR, review a pull request, or run SQL/warehouse analysis against a dataset — and when the user wants two agents or parallel reviewers/investigators on the same work. Covers the explore-vs-session routing call, deciding where the code lives (this project's repo vs cloning an external GitHub repo) or where the data lives, finding the repo with gh, spawning sessions in parallel, dual PR reviews, and reporting results back. Triggers: 'implement', 'fix the bug', 'make the tests pass', 'work this ticket', 'refactor this', 'open a PR', 'review this PR', 'run two agents on it', 'query the warehouse', 'analyze this dataset'.
Convert Word (.doc, .docx), PowerPoint (.ppt, .pptx), Excel (.xls, .xlsx), OpenDocument (.odt, .ods, .odp), RTF, EPUB, CSV, and PDF files to GitHub-Flavored Markdown. Use when a task needs the contents of an office document, spreadsheet, presentation, ebook, or PDF you cannot read directly.
Deep research agent skill. Use when the user needs thorough, scientific, truth-seeking research on any topic -- investigating claims, finding primary sources, synthesizing evidence, producing cited reports. Triggers on: 'research this', 'investigate', 'deep dive', 'find sources', 'what does the evidence say', 'literature review', 'fact check', 'analyze the research on', any request requiring multi-source investigation with citations.
Artifact-agnostic design guidance — works for CSS, PowerPoint, matplotlib, PDF, or any visual output. Also includes a curated catalog of named font/color themes for slides, docs, and reports (non-web assets).