agentleFS
JakkuSakuraJakkuSakura/skills/axum-single-page-ui/SKILL.md

axum-single-page-ui

Skill1 starsChanged 9 months agoMITView on GitHub

Build and serve a single-page web UI from an Axum service, including plain-JS mode and optional TypeScript build/fallback patterns.

The file

Show its rules and text

We split this skill into the rules it gives an agent

21 rules. About 0 are common, 13 are distinctive, and 8 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈13

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 8

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use this skill when the user wants a single-page UI served by axum from the same Rust service as API routes.

    line 10
  2. Distinctive:

    Prefer plain JS + single HTML for fastest, lowest-risk delivery.

    line 21
  3. Distinctive:

    Keep API unchanged; only adjust UI asset serving and frontend script.

    line 22
  4. Distinctive:

    Use TypeScript only when user explicitly asks for it.

    line 23
  5. Very specific:

    Keep frontend as single page (one index.html) with client-side rendering.

    line 33
  6. Distinctive:

    Use when speed and operability matter more than tooling.

    line 39
  7. Distinctive:

    No TS type checking

    line 50
  8. Distinctive:

    Use when frontend complexity grows.

    line 55
  9. Distinctive:

    Use only when explicitly requested.

    line 70
  10. Distinctive:

    Never enable fallback silently in production

    line 76
  11. Distinctive:

    Add visible UI banner when fallback mode is active

    line 78
  12. Distinctive:

    Keep API and UI concerns separate:

    line 82
  13. Very specific:

    Do not let SPA fallback intercept /api/*

    line 85
  14. Very specific:

    Keep /health independent and always fast

    line 86
  15. Distinctive:

    When table/count mismatch appears (e.g., count shows rows but table is empty):

    line 90
  16. Distinctive:

    Verify API payload shape matches renderer field names.

    line 92
  17. Distinctive:

    Check runtime JS errors in browser console before patching backend.

    line 95
  18. Very specific:

    Prefer robust field fallback mapping in UI (currency || symbol, etc.).

    line 96
  19. Very specific:

    Keep <tbody> children as actual <tr> nodes only.

    line 111
  20. Very specific:

    When a package has deployment.yaml, deploy with:

    line 139
  21. Very specific:

    Check one /api/... endpoint and / page rendering

    line 147

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Axum Single Page UI

Use this skill when the user wants a single-page UI served by axum from the same Rust service as API routes.

When to use

  • Axum backend needs to serve one UI page at /
  • UI and API are in one service (/api/* + browser UI)
  • User wants plain JavaScript first, with optional TypeScript path later
  • User asks for runtime/browser transpile trade-offs or fallback design

Defaults

  • Prefer plain JS + single HTML for fastest, lowest-risk delivery.
  • Keep API unchanged; only adjust UI asset serving and frontend script.
  • Use TypeScript only when user explicitly asks for it.
  • For production reliability, prefer build-time compilation over runtime transpilation.

Canonical architecture

  1. axum routes:
    • GET /health
    • GET /api/... for JSON APIs
    • GET / for SPA shell
  2. Serve static frontend assets with tower-http (ServeDir/ServeFile) or embed via include_str!/include_bytes!.
  3. Keep frontend as single page (one index.html) with client-side rendering.

Implementation patterns

Pattern A: Plain JS single-file page (default)

Use when speed and operability matter more than tooling.

  • One HTML page with inline <script type="module">
  • Optional CDN dependencies (e.g., SolidJS, Tailwind)
  • Axum returns the page directly or as embedded static asset

Pros:

  • Zero frontend toolchain
  • Easiest deploy/debug

Cons:

  • No TS type checking
  • Harder to scale frontend complexity

Pattern B: TS build + Axum static serving

Use when frontend complexity grows.

  • Author UI in tsx/ts
  • Build to static assets (index.html, app.js, app.css)
  • Axum serves built assets

Pros:

  • Type safety and better maintainability
  • Better performance/caching

Cons:

  • Adds build pipeline

Pattern C: Build-first + runtime transpile fallback (opt-in)

Use only when explicitly requested.

  • Primary: prebuilt bundle from build/deploy
  • Fallback: runtime/browser transpile path (feature-flagged)

Rules:

  • Never enable fallback silently in production
  • Gate fallback with explicit env flag (e.g., UI_TRANSPILE_FALLBACK=1)
  • Add visible UI banner when fallback mode is active

Route structure guidance

  • Keep API and UI concerns separate:
    • Router::new().nest("/api", api_router)
    • UI fallback for / and frontend routes
  • Do not let SPA fallback intercept /api/*
  • Keep /health independent and always fast

Frontend data contract guidance

When table/count mismatch appears (e.g., count shows rows but table is empty):

  1. Verify API payload shape matches renderer field names.
  2. Confirm rendering loops receive arrays (Array.isArray(payload)).
  3. Validate filter/query param names on both sides.
  4. Check runtime JS errors in browser console before patching backend.
  5. Prefer robust field fallback mapping in UI (currency || symbol, etc.).

Known repeated issue: counter updates but table looks empty

Symptom:

  • Header/count shows rows (for example Top Pairs: 200), but <tbody> appears empty.

Likely root cause in Solid template mode:

  • Using control-flow components directly inside table sections (<tbody><Show>...<For>...</For></Show></tbody>) can produce invalid table child nodes in some runtime/parser paths.

Reliable fix:

  1. Keep <tbody> children as actual <tr> nodes only.
  2. Replace table-local <Show>/<For> wrappers with a single function expression in <tbody>.
  3. Return either:
    • one fallback <tr> for empty state, or
    • rows.map(...) of <tr> templates for data rows.

Reference rendering pattern:

<tbody>
  ${() => {
    const rows = pairs();
    if (rows.length === 0) {
      return html`<tr><td colspan="6">No pair matched the current filters.</td></tr>`;
    }
    return rows.map((row) => html`<tr>...</tr>`);
  }}
</tbody>

Verification checklist:

  • API returns non-empty array (/api/v1/pairs/select?...).
  • Served HTML contains the const rows = pairs(); table-body renderer.
  • Browser console has no runtime render errors.

Deployment guidance

When a package has deployment.yaml, deploy with:

  • infra deploy --package <app>

After deploy:

  • Check rollout status
  • Check /health
  • Check one /api/... endpoint and / page rendering

Output checklist for Codex

For implementation tasks, return:

  1. Files changed and why
  2. Commands run for verify/deploy
  3. API/UI smoke-check results
  4. Any fallback flags or operational caveats

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.