Llama Coder Documentation

repository·main·Indexed 25 days ago

https://github.com/nutlope/llamacoder

An open-source implementation of Claude Artifacts powered by Llama 3 on Together.ai. Llama Coder allows users to generate small applications from a single prompt using a browser-only preview renderer with esbuild-wasm. The documentation covers local setup, environment configuration, the generateApp() function, prompt engineering strategies via PromptConfig, and the @llamacoder/preview-kit-baseui component library.

Tokens
4.3K
Snippets
4
Records
31
Agent score
92%

What's inside Llama Coder

  1. Understand the Preview Renderer architecture

    main

    The LlamaCoder preview renderer is a browser-only runtime that uses esbuild-wasm to compile generated application files directly in the user's browser. It operates within a sandboxed iframe and uses import maps to resolve dependencies.

    Resolution logic:

    • Static preview substrate: Resolved via import maps to prebuilt files located in /public/preview-vendor.
    • Dynamic npm packages: Any non-static allowed npm packages fall back to pinned esm.sh URLs.

    This architecture allows for modern library support (e.g., Recharts, Radix, framer-motion), better error reporting via a custom bridge, and detailed performance timing (bundle time, runtime import/render time, and total time to ready).

  2. Configure environment variables for Llama Coder

    main

    Create a .env file in the root directory and provide the following required and optional environment variables:

    • TOGETHER_API_KEY: Your Together AI API key for LLM inference.
    • DATABASE_URL: A PostgreSQL connection string (e.g., from Neon) for Prisma.
    • BRAINTRUST_API_KEY (optional): Your Braintrust API key for observability.
    TOGETHER_API_KEY=<your_together_ai_api_key>
    DATABASE_URL=<your_database_url>
    BRAINTRUST_API_KEY=<your_braintrust_api_key>
  3. Clone and run Llama Coder locally

    main

    To run Llama Coder on your local machine, clone the repository, configure your environment variables, install dependencies, and start the development server.

    git clone https://github.com/Nutlope/llamacoder
    # After creating .env file...
    npm install
    npm run dev
  4. Optimize Preview performance during streaming

    main

    When the Preview tab is open while text is streaming, the system may trigger a full re-bundle and iframe reload for every single incoming chunk. This happens because every chunk changes the filesKey.

    Optimization: To prevent excessive re-bundling, implement a debounce (recommended: 300-500ms) while streamText is non-empty. This ensures that the preview only updates after the stream has paused or reached a stable state, rather than on every individual chunk.

  5. Fix False 60s Watchdog Failures on Identical Files

    main

    When calling renderFiles with content that is byte-identical to the current srcdoc, React may skip updating the DOM attribute, preventing the iframe from firing the load event and posting the ready message. This causes the 60s watchdog to report the code as broken even though it is running.

    Fix: Short-circuit the process when the new srcdoc equals the current one. Instead of reloading the iframe, transition the state directly to ready since the content is already live.

  6. Fix Stuck-White Preview in Hidden Tabs

    main

    If the preview panel appears pure white with no spinner or error when a tab is hidden or occluded, it is likely due to Chromium not rasterizing the srcdoc iframe surface.

    To resolve this, ensure the srcdoc bridge (implemented in lib/preview/html.ts) uses a paint keep-alive mechanism: while document.hidden is true, an imperceptible 1x1 fixed pixel should alternate its background every 500ms. This creates persistent real paint damage, forcing Chrome to re-raster the frame once the tab becomes visible.

  7. Troubleshoot 'Preview did not report ready or error within 60s'

    main

    If you encounter the error message "Preview did not report ready or error within 60s" despite the generated code being correct, it is likely a module-load failure rather than an application logic error. This occurs when an inline <script type="module"> fails to load, preventing the execution of __previewMarkAppReady and bypassing the error bridge.

    Common Causes:

    • Unresolvable Specifiers: The generated app imports a bare specifier (e.g., import 'three') that is not defined in the preview's import map (outside of PREVIEW_DEPS or the baseui vendor list).
    • Network Failures: A vendor file returns a 404, or an esm.sh request hangs/fails due to a cold cache.
    • Static Import Failures: Any static import in the bundled output cannot be fetched.

    Debugging Steps:

    • Check if the app attempts to import external libraries not included in the preview environment.
    • Verify that all external specifiers used in the code are covered by the available import maps.
  8. Resolve localStorage Tailwind CSS cache quota issues

    main

    The preview system caches compiled CSS snapshots in localStorage using keys prefixed with llamacoder-preview-tailwind-css:. Because these snapshots can be up to 1MB each and localStorage has a limited quota (typically ~5MB), the cache may stop working after a few dozen entries.

    Symptoms:

    • setItem calls fail silently due to quota exhaustion.
    • Every session requires a fresh, slow in-iframe Tailwind compilation (no perceived caching).

    Recommended Fixes:

    • Eviction Policy: Implement a prefix scan to evict old llamacoder-preview-tailwind-css: keys using an LRU (Least Recently Used) strategy, capping the cache at approximately 10 entries.
    • Migration: Move the CSS cache from localStorage to the existing IndexedDB llamacoder-preview database to leverage a much larger storage quota.
  9. Fix Tailwind-ready Probe Timeout

    main

    If every preview is waiting for the full 5000ms timeout before showing, it is likely because the Tailwind-ready probe is being removed too quickly. Tailwind v4 browser compilation is asynchronous; if a probe element is appended, measured, and removed in the same frame, the scanner never sees the classes.

    Fix:

    1. Keep one persistent probe element attached (e.g., position:fixed; left:-9999px).
    2. Poll its computed style in a loop.
    3. Remove the element only after the ready signal fires.
    4. For precompiled-CSS paths, skip the probe entirely.
  10. Prevent Preview Reboot on Tab Switch

    main

    Switching between the 'Code' and 'Preview' tabs currently unmounts the CodeRunner and its iframe, causing a full reboot (re-parsing imports, re-fetching modules, and re-running React) every time the user toggles views.

    Fix: Instead of using a ternary operator to mount/unmount components, keep both panes mounted in the DOM and toggle their visibility using CSS (hidden or display:none). This ensures the iframe remains alive and ready when switching back to the Preview tab.

  11. Fix 'Preview did not report ready or error within 60s' error

    main

    The error message Preview did not report ready or error within 60s often occurs because the readiness pipeline (app-ready trailer, bridge load handler, and Tailwind-ready watch) was incorrectly using requestAnimationFrame (rAF). Since Chrome suspends rAF in hidden/occluded tabs, the readiness signal never fires if a user tabs away during generation.

    Fix: Replace rAF-based readiness with timer-based polling (e.g., setTimeout), which continues to run (though throttled) in hidden tabs.

  12. Configure app generation with GenerateAppConfig

    main

    The GenerateAppConfig object allows you to customize the generation behavior of generateApp.

    Configuration Options

    KeyTypeDefaultDescription
    promptVersionPromptVersion"current-v0"Specifies which prompt template to use (e.g., "minimal-v1", "current-v0-plan-v2").
    archModeArchMode"separate"Determines how the architecture is handled: "separate" (two-step: plan then code), "none" (direct prompt to code), or "inline" (single step with internal planning instruction).
    temperaturenumber0.4Controls randomness of the output.
    maxTokensnumberDynamicMaximum tokens to generate. Defaults to 13000 for "separate" or "inline" modes, and 9000 for "none" mode.
    promptConfigPromptConfigundefinedAdditional configuration for the prompt engine.

    Supported ArchModes

    • "separate": Uses a PLANNING_MODEL to create a software architecture plan before generating code. This is the highest quality mode.
    • "inline": Sends the prompt directly to the coding model but appends an instruction to plan internally. Faster than "separate" but less robust.
    • "none": Sends the raw prompt directly to the coding model with no planning step. Lowest quality/fastest.