AI
The scorecard for models
Every point a previous page would have held against BaseNative, with an honest status. Fixed means the runtime or the docs changed. Mitigated means a tool exists and the gap is still real. Accepted means the tradeoff stands.
Where this list came from
Searches of this repository's history, branches, and closed pull requests found no
/ai page and no commit by Muse. Nothing was restored from a deleted file, because
no such file exists. The rows below are the last committed list of points against BaseNative:
the compare page (Where others win, Probably not, and the
developer-experience rows), the October 2026 LLM benchmark those pages cite, and the write-up in
the benchmark blog. greenput.com/ai is a
page about GreenPut, a different product. It is not this scorecard.
The short file to read before writing UI is /llms-start.txt (docs/llm/START.md). llms.txt stays the package index.
Measured now
These figures are read from the repository when the page renders. The token pair is the historical benchmark. It is not a new measurement, and it is not a claim that the code got smaller.
Every point against it
An effect that reads a signal and a computed derived from it runs once. The historical benchmark still counts one app-code fix for the old double-fire.
| From | Point | Status | Standing |
|---|---|---|---|
| Where others win | No framework component layer, and no component-library ecosystem on top of HTML | Accepted | Semantic HTML is the component model. That is the design, not a missing feature. |
| Where others win | Ecosystem of one, with no third-party component libraries | Accepted | Nothing on npm supplies a BaseNative component library. The in-repo catalog is @basenative/components. |
| Where others win | Runtime expression parsing has overhead versus compiled output | Accepted | Templates stay data, so a model can emit them under a strict CSP with no build. A compiler would give that up. |
| Where others win | Svelte has the better-polished DX and a mature compiler toolchain | Accepted | Compiled DX is still ahead. The counterweight is no compiler in the agent loop. |
| Where others win | No React DevTools, no Angular CLI, and no Svelte inspector | Mitigated | enableDevtools() sets globalThis.__BASENATIVE_DEVTOOLS__. That is not a browser extension. The bn CLI scaffolds and deploys. |
| Where others win | Solo-maintained, with a bus factor of one | Accepted | One maintainer. Distribution does not change that. |
| Where others win | Almost nobody has heard of it, so hiring and onboarding start from zero | Accepted | This page, the cheat sheet, AGENTS.md, and package keywords are the response. They are not a community. |
| Probably not | Large team apps that need an enforced architecture | Mitigated | @basenative/validate and the MCP server reject foreign syntax. They are not a staff engineer. |
| Probably not | Projects that need deep third-party integrations | Mitigated | Auth, db, upload, and the Plaid wrapper exist in this repo. Most of npm does not have a BaseNative adapter. |
| Probably not | Apps where a mature devtools inspector is a critical part of the workflow | Mitigated | Same gap as the missing browser extension. Use enableDevtools() or do not pick BaseNative for that workflow. |
| Probably not | Enterprise apps with a strict hiring-pool requirement | Accepted | There is no hiring pool. Do not pretend otherwise. |
| Probably not | Complex SPAs with hundreds of components | Accepted | Router, forms, and the in-repo catalog exist. There is no npm component ecosystem to assemble a huge SPA from. |
| DX table | Ecosystem packages are Growing against a massive React ecosystem | Accepted | The DX table still says Growing. The word is accurate. |
| DX table | Community size is a solo project | Accepted | The DX table still says Solo project. |
| DX section | The place BaseNative is furthest behind | Mitigated | HMR already ships. A CDN file, bn from-jsx, and agent rules shorten the first hour. Compiled-DX parity is not claimed. |
| LLM benchmark | More code tokens than React, because HTML templates carry closing tags | Accepted | The October 2026 measurement stands: fewer lines, more tokens. The frozen benchmark apps were not rewritten. |
| LLM benchmark | The docs bundle has no break-even through code savings | Mitigated | llms.txt stays an index. docs/llm/START.md is a separate short file, also served as /llms-start.txt. Code savings still do not pay for the index. |
| LLM benchmark | An effect that read a signal and a computed derived from it fired twice | Fixed | A set() now settles derived computeds and then runs each affected effect once. The historical run still recorded one app-code fix. |
| October blog | :class used to replace the class attribute instead of merging | Fixed | mergeClass() joins class and :class on the server and in hydrate(). A false binding adds nothing. |
| October blog | An effect that reads a signal it writes used to overflow the stack | Fixed | That pattern throws BN_EFFECT_LOOP and names .peek(). A read inside a helper still subscribes. |
| October blog | :value used to write the attribute instead of the property | Already fixed | Fixed in 2.0.1. :value and :checked mirror the DOM property, so clearing a signal clears the field. |
| October blog | Two small tasks are not a field study, and routing, forms, auth, and the database adapters went unbenchmarked | Accepted | No model pass rate is published. The eval corpus is empty and was not generated to fill this row. |
| README | The README told models to install from GitHub Packages | Fixed | The quick start now says npmjs.org, with no token. The old GitHub Packages page carries an out-of-date banner. |
Copy this counter
One HTML file. The runtime loads from a CDN. No bundler. The same template is what
render() accepts on the server.
<p class="item" :class="count() > 0 ? 'done' : ''">
Count <span>{{ count() }}</span>, doubled <span>{{ doubled() }}</span>
</p>
<button type="button" @click="count.set(count() + 1)">Add</button>
<script type="module">
import { signal, computed, hydrate } from 'https://cdn.jsdelivr.net/npm/@basenative/runtime@2/+esm';
const count = signal(0);
const doubled = computed(() => count() * 2);
hydrate(document.body, { count, doubled });
</script>
React habits that fail
bn from-jsx rewrites this subset of a draft.
@basenative/validate reports the same mistakes with the replacement.
- className and htmlFor
- Use class and for. An expression goes in :class, and it merges with the static class.
- onClick={save}
- Use @click="save($event)". The event name is lowercase after the @.
- A single brace around a value
- Text interpolation is {{ name() }}, with the signal called. A single brace is reported as React syntax.
- useState, useMemo, useEffect
- signal, computed, and effect. The setter is count.set, not setCount.
- An effect that logs by appending to the same signal
- Read that signal with .peek(), or write a different one. Otherwise the runtime throws BN_EFFECT_LOOP.
- Putting every class token inside :class
- That was the workaround when :class replaced the attribute. Write class="item" :class="done() ? 'done' : ''" now.