If you've written modern Angular, you probably miss a few things when you step outside it: the @if / @for control-flow syntax, templates with [prop] and (event), components with inputs and outputs, dependency injection, a router. If you've written React or Preact, you may miss something else: not shipping a framework's worth of bytes to render a button.
AngeLite is my attempt to have both. It's a signals framework with Angular-style templates, a core of about 6 KB gzip when templates are precompiled, no Zone.js, no virtual DOM, and a security model that assumes your data is hostile. This post is the "why"; the rest of the series is the "how".
Repository: duvanjamid/angelite ยท Docs (English and Spanish): duvanjamid.github.io/angelite-docs
The 30-second version
import { signal, component, mount } from '@duvanjamid/angelite';
class Counter {
count = signal(0);
inc() { this.count.update(n => n + 1); }
}
component(Counter, {
selector: 'app-counter',
template: `<button (click)="inc()">Clicks: {{ count() }}</button>`
});
mount(Counter, document.body);
No build step required either: include a <script> tag and templates compile in the browser (about 10 KB gzip including the compiler). When the app grows, precompile templates and ship only the runtime (about 6 KB). The component code doesn't change.
What it's built from
Three ideas:
-
Signals (
signal,computed,effect). State lives in reactive values; when one changes, only what depends on it updates. There is no global change detection. -
Angular-style templates. HTML with
{{ }},[prop],(event),@ifand@for, compiled once into a list of instructions. There is no virtual DOM: creating a view is cloning the HTML and applying the instructions. - Optional modules. The core is small; the router, forms, HTTP client, i18n, animations, SSR, DevTools and a 33-component accessible UI library are separate imports you pay for only if you use them.
Why not just use X?
An honest answer, because the project's comparison page is honest about it too:
- If you need the ecosystem, hiring pool and a decade of battle-testing, use React, Vue or Angular. AngeLite has no track record, no external security audit and a very small community.
- If you want Preact-sized output but Angular-shaped templates and signals, that's the gap AngeLite aims at.
- If you want a small, secure-by-default UI layer for widgets, dashboards or embedded apps, where bundle size and strict CSP matter more than ecosystem, that's the sweet spot.
The four commitments
Small
An app with precompiled templates weighs as much as the lightest framework in the project's benchmark: about 6.1 KB gzip for the table app versus Preact's 6.2 KB. What you don't import isn't downloaded: forms add about 0.9 KB, HTTP 1.3 KB, i18n 0.7 KB, and so on, each only for those who import them.
Fast without tricks
Fine-grained signals, delegated events and keyed list reconciliation. Crucially, a performance budget runs in CI, so a new feature can't quietly make the core slower (post 4).
Secure by default
Interpolation is always text. URLs are filtered. [innerHTML] requires an explicit trustHtml(). Expressions can never reach window. There's no eval or new Function anywhere, so it works under a strict CSP and Trusted Types (post 3).
Familiar
If you've written Angular 17+, you already know the syntax: @if, @for, [prop], (event), [(ngModel)], pipes, inputs and outputs. What changes is state: you write to signals instead of mutating properties.
A short history (and a rewrite)
AngeLite started as an earlier, larger iteration (decorators, directives, its own forms and router). The version described in this series is a deliberate rewrite around a small signals core. The old, unhardened code was removed from the tree (it stays in git history) and the new one was built under a rule: no feature lands if it breaks the performance budget, and the security model is tested against real attack payloads rather than assumed.
What this series covers
- Why AngeLite (this post)
- Signals, templates and fine-grained updates, with no Zone.js and no virtual DOM
- Secure by default: six gaps I found in my own framework
- A performance budget that runs in CI
- Optional by design: the module system and what each core feature costs
- Honest benchmarks and an honest comparison
- SSR, hydration and "the blueprint is data"
Try it
npm install @duvanjamid/angelite
Or drop in the script bundle from the docs and open an HTML file. The documentation has runnable examples, a component library page with live controls, the benchmark, and a feature-by-feature comparison (including what's missing).
Next post: how a signal, a template and a microtask turn into DOM updates in about 750 lines of runtime.
Top comments (0)