Browser-native language Readable in. Native out.

Interfaces,
stitched ahead
of time.

A typed, indentation-first language for browser interfaces. Readable source, focused DOM updates, and a browser-native boundary.

Compile modelAhead of time
Compiler coreRust
Public boundaryWeb Components

Needle Studio

A little source. Something you can touch.
Ncounter.needleexample

Change count to 12, run the example, then try the counter.

Source Original example
Ln 1, Col 1Tab leaves editor · Ctrl / ⌘ + Enter runs
Example ready2 state slots · 1 text binding
Browser demo · not the production Rust compilerSource drafts stay in this browser.

See the idea. Inspect the work. Preview a fixture, follow its effect plan, then read the illustrative JavaScript.

How the compiler is designed

Friendly to read.
Precise underneath.

Needle keeps the component legible without making the compiler guess. Types, identity, lifetimes, and browser boundaries stay visible in the source.

01

One file, one readable unit

State, structure, behavior, and styles stay close enough to understand.

The syntax is compact, but the important decisions do not disappear into convention or compiler magic.

typed stateexplicit eventsscoped styles
counter.needlesource sketch
component Counter as counter-view:
  state count i32 = 3

  view:
    output {count}
    button "Increase" on click:
      count += 1

  style:
    radius 24px
02

Planned, not diffed

Bindings become exact browser operations.

Changing count already knows which text node should move.

count → output.textContent
03

Browser-shaped output

Needle ends at standards you already know.

Custom Elements, static CSS, declarations, and maps remain inspectable.

<counter-view>
04

Runtime by evidence

Helpers appear only when a feature proves it needs them.

No universal client engine is assumed by default.

features → helpers
Readable source.needle
→
Typed programRust AST
→
Known effectsDOM plan
→
Ordinary filesJS · CSS · DTS

A soft surface over a
hard compiler.

The friendly syntax sits on a deliberate Rust pipeline. Needle reads the whole component, proves what it can, and leaves the browser with a concrete plan.

needlecIllustrated Rust pipeline
design walkthroughtarget/browser
Stage 01 / Parse

Rust reads structure, not a template string.

Indentation, directives, and declarations become a typed syntax tree with precise source spans for diagnostics.

    Binding1 dependencycount
    Effect1 known writetextContent
    Boundary1 custom elementcounter-view
    ↯

    Direct updates

    Text, attributes, classes, styles, and lists receive purpose-built operations.

    ◇

    Readable artifacts

    Generated JavaScript, CSS, declarations, and maps remain ordinary project files.

    ◎

    Stable boundary

    Custom Elements let Needle live beside another stack—or outlast it.

    The important ideas,
    in language sketches.

    Explore the intended shape of Needle’s core surface: explicit identity, visible lifetimes, scoped styling, and optional Rust through a typed boundary.

    Pattern 01 / Typed state

    State stays beside the view.

    1 state slot1 text edge1 listener
    state.needle
    Identity

    Keys are a language decision.

    Collections preserve the nodes that should survive, rather than relying on an incidental loop shape.

    Lifetime

    Cleanup belongs beside creation.

    Requests, subscriptions, effects, and branches carry a visible disposal path.

    Boundary

    Interop is explicit.

    Props, events, slots, and Rust calls cross typed boundaries you can inspect.

    The details are part of the design.

    Advanced mechanics stay available when an application needs them, without crowding the first ten lines of a component.

    SourceStatic analysisBrowser work
    01
    Fine-grained dependency plansState changes already know their destination.

    Each binding creates a compiler dependency edge. Emitted code runs only the operations attached to that edge.

    count → value.textContent
    02
    Keyed collection identityLists preserve the nodes that should survive.

    Keys are language syntax rather than a loose convention, giving the compiler a stable reconciliation path.

    key task.id → node record
    03
    Resource cleanupAsync work owns an abort and disposal path.

    Requests, subscriptions, and effects connect to component and branch lifetimes during compilation.

    branch leaves → abort()
    04
    Scoped style outputLocal source still becomes ordinary CSS.

    Selectors are rewritten into stable local output that remains understandable in browser tooling.

    .card → .n-card_k7m2
    05
    Web Component contractsProps and events cross a platform boundary.

    Public props, attributes, methods, slots, and events compile into a documented Custom Element contract.

    <search-box value="needle">

    Follow the thread.

    Compiler notes, language sketches, and the next thing worth trying. A small update when there’s something to share.

    Language & compiler notesNew examples to exploreEarly design discussions
    Needle Studio

    A few useful shortcuts.

    The editor works with your keyboard, not against it.

    Run this example
    Ctrl / ⌘ Enter
    Indent a line or selection
    Ctrl / ⌘ ]
    Unindent a line or selection
    Ctrl / ⌘ [
    Move to the next control
    Tab
    Move between tabs
    ←→
    Close this window / focus mode
    Esc

    Source drafts are saved per example on this browser when storage is available. No account, no upload.

    Restore example

    Start with the original?

    This replaces your edited source for Counter. Your other examples are untouched.