Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when building any val with a user interface — dashboards, web apps, landing pages, forms, admin tools, anything users see in a browser. Covers JSX/React conventions, Twind/Tailwind styling, React version pinning, the view-source link requirement, and what to avoid (template-string HTML, external assets).
.claude/skills/hashgraph-online-react-ui/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 284% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 7% | 0% |
| case-11 | ✗→✓ | ▲ Improved | -49% | 0% |
| case-12 | ✗→✓ | ▲ Improved | -34% | 0% |
| case-13 | ✗→✓ | ▲ Improved | -21% | 0% |
For any val that renders a UI, prefer to build it with React components in .tsx files, unless the user states otherwise. The templates/react-hono-starter template is set up for this — start there with remix_val instead of building from scratch.
Put markup, styles, and scripts in real files — avoid template literal strings (e.g. new Response(\<html>...</html>\)). Code in template strings has no syntax highlighting, no linting, no type checking, and is unreviewable.
.tsx — React/JSX components, any UI with logic or interactivity.html — purely static markup.ts — server code and scriptsBuild UI component by component in .tsx files. Compose small components rather than rendering one giant page.
Prefer Twind to apply Tailwind utility classes at runtime — no build step required. Add the script to your HTML shell:
html<script src="https://cdn.twind.style" crossorigin></script>
Then use Tailwind classes directly in JSX:
tsx<div className="flex items-center gap-4 p-6 rounded-lg bg-white shadow"> <h1 className="text-2xl font-bold">Hello</h1> </div>
Avoid inline <style> tags, CSS-in-JS objects, or separate .css files, unless the user says otherwise.
Serve client modules with serveImmutableFile from std/utils — browsers cache them immutably, and publishing bumps the val's version, which invalidates automatically (full pattern: the client-side-js skill). A never-cached frontend/root.tsx shell (hono/jsx) stamps the entry and favicon with immutableFileUrl:
tsx// frontend/root.tsx — in the Root() HTML shell: <script src={immutableFileUrl("/frontend/index.tsx")} type="module" /> // index.ts: app.get("/", (c) => c.html(Root())); app.get("/__immutable/*", (c) => serveImmutableFile(c.req.path));
Every UI val should expose a way for users to see and remix its source. Both parts are required:
ts import { parseVal } from "https://esm.town/v/std/utils/index.ts"; app.get("/source", (c) => c.redirect(parseVal().links.self.val));
tsx <a href="/source">view source</a>
A common error — "Cannot read properties of null (reading 'useState')" — means a React sub-dependency is loading a different React version. Pin all React-related imports to 18.2.0:
tsimport SomeLib from "https://esm.sh/some-lib?deps=react@18.2.0,react-dom@18.2.0";
Do not use external images or hosted assets that may break. Prefer:
To send browser errors back to val logs (visible via get_logs), include this script in your HTML shell:
html<script src="https://esm.town/v/std/catch"></script>
After editing a UI val, call fetch_val_endpoint to confirm the page renders without error, then check get_logs for any client-side errors. Don't report the change as done without both.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 38,669 | 11,351 | -71% | 1 | 1 | 0% | 8,258 | 1,601 | -81% | 0 | 0 | — |
case-02 | fail→fail | 52,951 | 12,685 | -76% | 1 | 1 | 0% | 8,246 | 1,012 | -88% | 0 | 0 | — |
case-03 | fail→fail | 42,330 | 27,837 | -34% | 1 | 1 | 0% | 8,244 | 1,997 | -76% | 0 | 0 | — |
case-04 | pass→fail | 14,699 | 25,453 | +73% | 1 | 1 | 0% | 2,900 | 1,201 | -59% | 0 | 0 | — |
case-05 | pass→fail | 17,959 | 26,943 | +50% | 1 | 1 | 0% | 2,307 | 1,512 | -34% | 0 | 0 | — |
case-06 | pass→pass | 19,242 | 57,575 | +199% | 1 | 1 | 0% | 2,697 | 9,080 | +237% | 0 | 0 | — |
case-07 | fail→pass | 17,009 | 68,836 | +305% | 1 | 1 | 0% | 3,284 | 12,624 | +284% | 0 | 0 | — |
case-08 | pass→pass | 29,959 | 7,098 | -76% | 1 | 1 | 0% | 1,928 | 1,183 | -39% | 0 | 0 | — |
case-09 | fail→pass | 17,952 | 8,930 | -50% | 1 | 1 | 0% | 2,180 | 2,326 | +7% | 0 | 0 | — |
case-18 | fail→fail | 18,003 | 13,512 | -25% | 1 | 1 | 0% | 873 | 1,282 | +47% | 0 | 0 | — |
case-10 | pass→pass | 21,360 | 10,324 | -52% | 1 | 1 | 0% | 2,952 | 2,536 | -14% | 0 | 0 | — |
case-11 | fail→pass | 23,914 | 9,775 | -59% | 1 | 1 | 0% | 3,057 | 1,554 | -49% | 0 | 0 | — |
case-12 | fail→pass | 20,889 | 10,875 | -48% | 1 | 1 | 0% | 2,939 | 1,932 | -34% | 0 | 0 | — |
case-13 | fail→pass | 17,143 | 9,659 | -44% | 1 | 1 | 0% | 2,012 | 1,581 | -21% | 0 | 0 | — |
case-14 | fail→pass | 9,029 | 9,696 | +7% | 1 | 1 | 0% | 1,405 | 1,216 | -13% | 0 | 0 | — |
case-15 | pass→pass | 11,718 | 14,896 | +27% | 1 | 1 | 0% | 2,156 | 2,507 | +16% | 0 | 0 | — |
case-16 | pass→pass | 19,243 | 19,807 | +3% | 1 | 1 | 0% | 2,548 | 3,858 | +51% | 0 | 0 | — |
case-17 | fail→pass | 34,731 | 7,734 | -78% | 1 | 1 | 0% | 2,701 | 1,278 | -53% | 0 | 0 | — |
case-19 | fail→fail | 57,425 | 51,924 | -10% | 1 | 1 | 0% | 2,353 | 1,468 | -38% | 0 | 0 | — |
case-20 | fail→pass | 12,764 | 19,503 | +53% | 1 | 1 | 0% | 1,242 | 1,251 | +1% | 0 | 0 | — |
case-21 | fail→fail | 25,237 | 17,774 | -30% | 1 | 1 | 0% | 1,824 | 2,162 | +19% | 0 | 0 | — |
case-22 | pass→pass | 176,987 | 16,405 | -91% | 1 | 1 | 0% | 1,968 | 1,076 | -45% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 17 counted toward the lift figure. The other 5 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +27 percentage points is the difference between those two pass rates over the 17 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.