Blinc Roadmap

May 23, 2026 · View on GitHub

Last updated: 2026-04-13

Vision

Blinc is a GPU-accelerated, cross-platform UI framework that enables developers to build production-quality desktop, mobile, and embedded applications from a single Rust codebase. The framework aims to match the quality of native platform UIs while providing a unified developer experience across all targets.


Phase 1: Desktop Production Readiness

Goal: Make Blinc viable for shipping real desktop applications.

1.1 System Integration (P0)

FeatureStatusNotes
File dialogs (open/save/folder)DoneVia rfd crate, blinc_app::dialog module
System tray / status bar iconDoneblinc_app::tray::TrayIconBuilder via tray-icon + muda
Native OS notificationsDoneblinc_app::notify::Notification via notify-rust
Drag and dropDoneWindow-level on_file_drop() + element-level .on_file_drop() on Div
Clipboard (rich content)DoneCross-platform text + image via arboard crate
Global keyboard shortcutsDoneblinc_app::hotkey::GlobalHotkey via global-hotkey

1.2 Window Management (P0)

FeatureStatusNotes
Multi-window supportDonectx.open_window(config), WindowState, AppCommand event loop
Window min/max size constraintsDoneWindowConfig::min_size(), max_size()
Programmatic window positioningDoneset_position(), center(), set_size() on Window trait
Window state persistenceDoneWindowStateStore with JSON save/load
Modal window APIDoneWindowConfig::modal(), input blocking on non-modal windows
Custom title bar / drag regionsDone.drag_region() on Div, window_actions module

1.3 Input (P1)

FeatureStatusNotes
IME / compose inputDoneWinit Ime::Commit routed as Key::Char events, set_ime_allowed(true)
Context menu wiringDone.on_right_click() / .on_context_menu() on Div
Trackpad gestures (pinch/rotate)Done.on_pinch() / .on_rotate() on Div, winit gesture events

1.4 Missing Widgets (P1)

Layering rule (applies to every widget in this section and §1.5): all blinc_layout::widgets::* widgets must render with theme tokens by default — colours from ColorTokens, radii from RadiusTokens, shape from ShapeTokens, spacing from SpacingTokens, typography from TypographyTokens, easings from AnimationTokens. A bare text_input(...), slider(...), number_input(...) built against the platform default bundle should look right out of the box — theme-aware, dark-mode-aware, variant-aware (Restrained / Hybrid / Expressive). blinc_cn then layers shadcn-flavoured surface styling and micro-interactions on top via CSS classes and themed wrappers (the same way cn::input wraps blinc_layout::text_input today: the layout widget already paints itself from the active theme; cn contributes the .cn-input border-shape / focus-ring / hover-bg overlay and a few interaction polishes like the outline-offset transition). This keeps the layout widgets useful outside a cn_bundle() install — anyone building a custom theme bundle gets cohesive defaults without depending on blinc_cn.

WidgetStatusNotes
Date pickerPlannedCalendar grid + input. See §1.5 for the cn component sizing.
Time pickerPlannedClock face or dropdown. See §1.5.
Color pickerPlannedHSL/RGB wheel + swatches. See §1.5.
Range slider (dual thumb)PlannedExtend existing slider. See §1.5.
Number input (stepper)PlannedFirst-class blinc_layout::widgets::number_input — typed numeric value (i64 / f64), parse + clamp + commit FSM, increment/decrement keyboard handling (↑/↓/PageUp/PageDown), step/min/max/precision config, wraps text_input for the visible field. cn::number_input then themes it (see §1.5).
Data gridPlannedSortable, filterable table. See §1.5 (depends on cn::table).
Virtualized listDonevirtual_list(count, builder) — variable-height items, CSS classes, flexbox layout
Rich text editorDonerich_text_editor() — formatting toolbar, undo/redo, selection, clipboard

1.5 cn Component Library — shadcn/ui parity gaps (P1)

blinc_cn currently ships 45 components. The remaining gaps to reach full shadcn/ui parity, plus the §1.4 widgets re-framed as their intended cn::* landing surface. Effort is rough: XS < 1 day, S 1–3 days, M ~1 week, L 2+ weeks. Priority follows shadcn parity + common request frequency.

ComponentPriorityEffortPrereqNotes
cn::toggleP0XSSingle binary toggle button. Reuse button + Stateful with ToggleState. Pairs with :aria-pressed styling.
cn::toggle_groupP0XScn::toggleRadio-style toggle bar; single- or multi-select variants.
cn::number_inputP0XSblinc_layout::number_input, cn::inputThemed wrapper around the first-class number_input widget — applies cn surface (.cn-input-shaped border/focus ring, hover bg) plus the chevron up/down stepper buttons. Parse / clamp / commit logic lives in the layout widget; cn only contributes look + the stepper affordance. Roadmap §1.4 entry.
cn::tableP0Sblinc_layout::tableThemed wrapper exposing Table / TableHeader / TableBody / TableRow / TableCell / TableCaption builders matching the shadcn surface. No sort/filter — that's data_grid.
cn::input_otpP0Scn::inputSegmented PIN / OTP input (N digits). Focus chain across boxes with auto-advance on type, auto-rewind on backspace, paste fills all slots.
cn::calendarP0MMonth grid + day cells + range / single selection. Hand-rolled date math (chrono is overkill for a UI calendar). Prereq for date picker.
cn::date_pickerP0Mcn::calendar, cn::popoverInput + popover-mounted calendar. Roadmap §1.4 entry.
cn::formP0MTyped schema + field-binding wrapper. Field States register into a form context; submit collects + validates. Should integrate with cn::input / cn::textarea / cn::select / cn::checkbox field variants surfacing error state via CSS class (e.g. .cn-input--invalid).
cn::range_sliderP1Scn::sliderDual-thumb extension. Most of the work is hit-testing the nearest thumb on drag start + clamping the trailing thumb against the leading one. Roadmap §1.4 entry.
cn::carouselP1Scn::scroll_areaHorizontal scroll-snap container + prev/next buttons + dot indicators + optional autoplay. A non-cn carousel_demo example exists as a reference.
cn::commandP1Mcn::combobox⌘K-style searchable command palette: fuzzy match, keyboard nav, grouped items, action shortcuts. Lifts the keyboard-driven half of combobox into a richer overlay surface.
cn::time_pickerP1Mcn::popover, cn::inputClock face or scrollable hours/minutes/seconds columns. Roadmap §1.4 entry.
cn::color_pickerP1Mcn::popover, cn::sliderHSL/RGB wheel (canvas-rendered), saturation/value square, hue slider, hex input, recently-used swatches. Roadmap §1.4 entry.
cn::data_gridP2Lcn::table, cn::virtual_list, cn::form, cn::checkbox, cn::dropdown_menuSortable, filterable, paginated, column-resizable, row-selectable table on top of virtual_list for performance. Roadmap §1.4 entry. Pulls in column-header sort indicators + filter dropdowns + selection state + per-row context-menu.

Phase 2: Mobile Production Readiness

Goal: Bring mobile targets to feature parity with desktop.

2.1 Input & Interaction (P0)

FeatureStatusNotes
Soft keyboard show/hideDoneAtomic flags polled in frame loop
IME / compose input (mobile)PartialBasic text input works, full compose candidates need InputConnection/UITextInput
Gesture recognizersDoneGestureExt trait: .on_tap(), .on_long_press(), .on_swipe() + pinch/rotate
Pull-to-refreshDonepull_to_refresh(callback) widget with threshold, max pull, indicator
Safe area insetsDonectx.safe_area, safe_top/right/bottom/left(), safe_width/height()
Haptic feedbackDoneNative bridge handlers on both platforms

2.2 Platform Integration (P1)

FeatureStatusNotes
Deep linking / URL schemesDoneblinc_router::handle_deep_link() + platform DeepLink parser
App lifecycleDoneResumed/Suspended/LowMemory events, Android full lifecycle mapping
Native bridge API (Rust side)Donenative_call(), native_register(), PlatformAdapter trait in blinc_core
Native bridge streamsDonenative_stream() — bidirectional data (camera, audio, sensors) with auto-cleanup

Push notifications, camera, location, biometrics, status bar theming are implemented as example native bridge extensions — not in the framework core, but as documented templates that demonstrate the bridge API:

  • Android: BlincNativeBridge.register("camera", "capture", handler) in Kotlin
  • iOS: BlincNativeBridge.shared.register(namespace:name:handler:) in Swift
  • Rust: native_call("camera", "capture", args) (planned API)

Blinc provides the bridge transport. Platform features ship as reference implementations users can copy and adapt.

2.3 Media (P1)

FeatureStatusNotes
Audio playbackDoneAudioPlayer — Desktop: rodio (Vorbis/WAV/FLAC), Mobile: native bridge
Video decodingDoneVideoDecoder — Desktop: OpenH264 (H.264 NAL → RGBA), Mobile: native bridge
AV frame utilitiesDoneFrame (RGBA/RGB/BGRA/YUV420/Gray, scale, convert) + AudioSamples (f32/i16/u8, resample, mono)
Audio recordingDoneAudioRecorder — Desktop: cpal, Mobile: native bridge stream
Video playerDoneVideoPlayer — play/pause/seek/volume, frame push API
Camera streamDoneCameraStream — RTC-like reactive capture, RGBA frame delivery
Audio widgetDoneaudio_player() — waveform canvas, MediaControls via Player trait
Video widgetDonevideo_player() — canvas surface, shared controls, dimensions
Player traitDoneShared Player trait for AudioPlayer + VideoPlayer + live streams
Live streamingDonePlayer::is_live(), LIVE badge, seek-less controls

Licensing: Desktop uses royalty-free codecs only — OpenH264 (Cisco's BSD, patent costs covered by Cisco), VP9, AV1, Opus, Vorbis. No ffmpeg, no patent-encumbered codecs. Mobile uses platform-provided codecs (OS handles licensing).

Example ExtensionStatusNotes
Push notificationsPlannedFCM/APNs example with bridge handlers
Camera captureDoneCameraStream → native bridge → RGBA frames via blinc_dispatch_stream_data FFI
Location servicesPlannedGPS via bridge example
Biometric authPlannedFingerprint/Face ID bridge example
Status bar themingPlannedLight/dark status bar bridge example

2.3 Navigation & Router (blinc_router crate)

See docs/plans/blinc_router.md for full design. See docs/book/src/advanced/routing.md for usage guide.

FeatureStatusNotes
Route definition & trie matchingDone/users/:id, *wildcard, nested routes, O(depth) trie
Scoped use_router() hookDoneThread-local router stack, nested router support
History managementDoneRouterHistory with push/replace/back/forward
Page transitionsDonePageTransition using AnimationPreset + SpringConfig
Navigation guardsDoneAuth guards with redirect/reject
Deep linkingDoneAuto-registered, zero-config: URI parsing + platform dispatch
Desktop deep linksDoneCLI --deep-link=, macOS/Windows/Linux URL scheme registration
iOS deep linksDoneblinc_ios_handle_deep_link() C FFI, auto-dispatched
Android deep linksDonedispatch_deep_link() from JNI intent, auto-dispatched
System back buttonDoneAuto-registered by RouterBuilder::build(), Key::Back dispatch
Named routingDonepush_named("user", &[("id", "42")]) reverse lookup
Route outletDonerouter.outlet() builds current view with scoped context
Stack navigatorDonestack() + motion() — documented integration pattern
Tab navigatorDoneblinc_cn::tabs() + router.push() — documented pattern
Bottom sheet navigationDoneblinc_cn::sheet() + router.outlet() — documented pattern
Animation suspensionDoneAnimatedValue::pause/resume, Spring::pause/resume — old views auto-clean via Drop
Nested route stacksDoneSub-routers via RouterBuilder, use_router() returns innermost

Phase 3: Blinc DSL (.blinc files via Zyntax)

Goal: a declarative, hot-reloadable UI language that drops onto the existing Blinc renderer without replacing the Rust builder API. Implemented by embedding Zyntax — its tiered Cranelift+LLVM JIT for development and its LLVM AOT path for shipping mobile binaries.

3.1 Language design

// .blinc: declarative UI with embedded logic

import { Color, SpringConfig } from "blinc"

component Counter {
  state count: i32 = 0

  view {
    col(gap: 16, align: center, justify: center) {
      text("Count: {count}")
        .size(32)
        .color(Color::WHITE)
        .animate(spring: SpringConfig::bouncy)

      row(gap: 8) {
        button("- Decrement") { on_click: count -= 1 }
        button("+ Increment") { on_click: count += 1 }
      }
    }
  }

  style {
    .self {
      background: var(--surface);
      padding: 24px;
      border-radius: 12px;
    }
  }
}

3.2 Architecture

The DSL is not transpiled to Rust. The grammar lives in Zyntax (.zyn PEG with semantic actions), and the runtime lifts Zyntax's tiered backend whole-cloth — no parallel compiler. Two distribution modes share the same core:

.blinc source
    |
    v
[Zyntax Grammar2] -> TypedProgram
    |
    v
[HIR lowering]    -> HirModule
    |
    +-----------------+----------------+
    |                                  |
    v                                  v
[Cranelift JIT]                  [LLVM backend]
  RuntimeEngine::Tiered            compile_module() -> .o
  hot-reload via                   ar / cc link -> .a or executable
  runtime.hot_reload(...)          (mobile static-link, desktop AOT)
    |                                  |
    v                                  v
[Live UI, dev hot-reload]      [Shipping binary, no JIT at runtime]

The join point is the HirModule produced by Zyntax's typed-AST → HIR lowering. Above it everything is shared (grammar, builtins, plugin registration). Below it the backend choice depends on platform and profile.

3.3 Crate layout

CrateRole
blinc_dsl_coreGrammar (include_str!("../grammars/blinc.zyn")), RuntimeEngine enum wrapping ZyntaxRuntime/TieredRuntime, codegen helpers. Shared by every consumer.
zrtl_blincZyntax runtime library — $Blinc$div / $Blinc$text / $Blinc$image / $Blinc$state_get,set / $Blinc$on_click_register / $Blinc$add_css registered against existing Div/Text/Image builders + BlincContextState. Statically linked, not loaded from disk.
blinc_dslRust embed API: dsl::component(path) -> impl ElementBuilder, inline! macro (P1), hot-reload integration via the existing hot_reload::watch_dir watcher.
blinc_dsl_codegenLLVM AOT pipeline, lifted from zyntax_cli/src/backends/llvm_aot.rs. Emits .o via target_machine.write_to_file(.., FileType::Object, ..), packages into .a (mobile static link) or links to executable (desktop AOT).
blinc_cli (extended)Standalone driver — blinc init, blinc dev, blinc build --target …. Bundles LLVM (via inkwell) + per-platform pre-built libblinc_<platform>.a so non-Rust users don't need cargo on their machine. Same shape as flutter build.

3.4 Distribution modes

Rust embed mode — for existing Blinc projects. cargo add blinc_dsl, then mix .blinc components with hand-written builders:

fn build_ui(ctx: &mut WindowedContext) -> impl ElementBuilder {
    div()
        .child(text("Hand-written"))
        .child(blinc_dsl::component("ui/login.blinc")?)  // embed
}

Standalone CLI mode — for non-Rust users. Download the blinc CLI binary (no cargo install required); scaffold a pure-.blinc project and ship it:

blinc init my_app          # scaffolds .blinc files, no Cargo.toml
blinc dev                  # JIT runtime + watcher
blinc build --target ios   # AOT, statically linked, .ipa-ready

Both modes consume the same blinc_dsl_core and zrtl_blinc.

3.5 Platform matrix

TargetModeEngineArtifact
Desktop devJIT, watcher hot-reloadTieredRuntime::development().blinc source loaded at launch
Desktop releaseJIT or AOT (user picks)TieredRuntime::production() or LLVM AOTJIT: .blinc shipped as resources / AOT: native binary, no DSL deps at runtime
iOSAOT only (JIT forbidden)LLVM AOTlibblinc_dsl_aot.a linked into Xcode build
AndroidAOT onlyLLVM AOTlibblinc_dsl_aot.a linked via NDK
WasmDeferredTracking Zyntax's wasm AOT story

3.6 Type checking and diagnostics — leverage Zyntax

Zyntax already produces typed ASTs with type inference, validates call signatures against registered NativeSignatures, and surfaces parse / lowering / compile errors with file:line:col spans. Blinc relays those — we do not add a parallel check layer.

What we get for free by registering $Blinc$* builtins with proper signatures:

  • Call-site arity / type checking. A text(42) call where the grammar declares text(s: string) -> Element becomes a Zyntax type error at compile time, not a runtime panic.
  • State field type inference. state count = 0 infers i32; count -= 1 is checked against that type. Mismatches surface at compile_typed_program time, before any HIR lowering runs.
  • Interpolation type checking. "Count: {count}" requires count to satisfy ToString (or whatever trait the interpolation builtin asks for); Zyntax's resolver enforces it.
  • Diagnostics with spans. Parse errors carry (file, line, col, len); lowering errors do too. We surface them through BlincDslError with the original span preserved, so the watcher / dev mode can paint a fallback overlay showing the failing file region.

What this means for the plan:

  • Phase 1 prototype lists "type checker" was the wrong framing; the prototype validates that registering builtin signatures correctly propagates Zyntax's checks to the user.
  • The risk-reduction probe should specifically exercise: (a) signature-mismatch errors land with usable spans, (b) state field reactivity types round-trip cleanly through the typed AST (is count exposed as i32 or State<i32> to subsequent expressions? — needs probing), (c) diagnostics from a hot-reloaded .blinc file are catchable and actionable, not panics.

The BlincDslError type wraps zyntax_embed::GrammarError / RuntimeError and exposes a .diagnostics() -> Vec<Diagnostic { file, span, severity, message }> so the dev-mode overlay can render them inline. No custom error machinery for type inference itself.

3.7 Hot reload

Zyntax's tiered backend uses beadie for on-stack replacement (see zyntax/crates/compiler/BEADIE_INTEGRATION.md). When a .blinc file is recompiled via runtime.compile_typed_program(...), beadie's TieredAdapter atomically swaps the function pointers via Bead::swap_compiled — including OSR for in-flight invocations of long-running functions. No per-component runtime.hot_reload(name, hir) call required from Blinc; the runtime handles state preservation across the swap on its own.

Plumbing on the Blinc side reduces to: .blinc file watcher (already shipped in 92d46b48's hot_reload::watch_dir) → re-parse + recompile via the same path used at first load. The frame loop calls the same component entry points; beadie hands them the new code on the next invocation.

Hot-reload is JIT-only by construction. iOS users always restart for code changes (LLVM AOT, no JIT).

3.8 Features

FeaturePriorityNotes
Component definitionsP0component Name { state, view, style }
Reactive stateP0DSL declares; BlincContextState owns the actual State<T> keyed by (InstanceKey, field)
Template expressionsP0{variable} interpolation lowered to Call("$Blinc$concat", …)
Scoped CSSP0style block lowered to Call("$Blinc$add_css", "…") at instantiation
Props / inputsP0Typed component parameters; map to Rust function args at the host boundary
Conditional renderingP0if/else blocks lower to Zyntax TypedStatement::If
List renderingP0for x in xs lowers to Zyntax iterator pattern
Event handlersP0Each on_click: { … } becomes a named function Component$handler_N; host wires Div::on_click(move |_| runtime.call::<()>("Component$handler_N", &args))
Slot / childrenP1Component composition via host-side child arrays
Animation declarationsP1animate, transition lowered to existing Blinc animation builders
Import systemP1Cross-file component references via Zyntax's import resolver
Hot reloadP0 (dev) / N/A (mobile).blinc watcher → runtime.hot_reload(); reuses CSS/asset hot-reload infra
Standalone CLI buildP1blinc build --target produces deployable binaries without cargo
LSP serverP2Autocomplete, diagnostics, go-to-definition
VS Code extensionP2Syntax highlighting, inline preview

3.9 Implementation sequencing

  1. Risk-reduction prototype (1–2 weeks). Counter component, two builtins ($Blinc$text, $Blinc$on_click_register), JIT only, Rust embed only. Validates:
    • Grammar → TypedProgramruntime.call round-trip
    • Host-Rust closures invoking DSL functions and vice versa
    • runtime.hot_reload semantics for stateful UI (does swapping a view fn invalidate widget state in BlincContextState?)
    • Grammar startup cost — target <50 ms; if higher, switch to pre-compiled .zpeg via include_bytes!
    • Diagnostic channel end-to-end. Force a type error (text(42)), an arity error (text()), a state-field-type mismatch (count: i32 = 0; count = "x"), and a parse error in a hot-reloaded file. Confirm each surfaces with usable file:line:col spans, not panics. This is what tells us whether Zyntax's type-checking and diagnostics are production-grade for our use case or whether we'll need to wrap them.
    • Reactivity round-trip through the typed AST. Does Zyntax see count (declared as state count: i32) as i32 or as some State<i32>-shaped wrapper inside expressions? Determines whether reactivity is a host-only concern or whether we need Zyntax-side type sugar.
  2. Core language + Rust embed v1 (3–4 weeks). Full grammar covering state/view/style/if/for/imports/events. zrtl_blinc covers all P0 builders. Hot-reload integration via the .blinc watcher branch. End state: any P0 Rust example portable to .blinc. Ships first — Rust users get value before standalone CLI lands.
  3. AOT pipeline + mobile (3–4 weeks). LLVM AOT lifted from zyntax_cli/src/backends/llvm_aot.rs, cross-compile triples driven by CARGO_CFG_TARGET_OS, .a packaging via ar, iOS/Android runner integration. Validate iOS no-JIT compliance.
  4. Standalone CLI mode (4–6 weeks). blinc init, project scaffolder, blinc dev for .blinc-only projects, blinc build driving the AOT pipeline, framework-prebuild CI producing per-platform libblinc_<platform>.a.
  5. Tooling + polish — error reporting with file:line spans, optimize_function warm-up of view fns at first frame, profiling, LSP / VS Code extension.

3.10 Patterns lifted from Zyntax codebase

  • Grammar embedding via include_str! — see zyntax/crates/zynml/src/lib.rs:77
  • Stdlib resolver closure for framework modules — zynml/src/lib.rs:186-197, install before module load
  • Plugins → grammar → module load order — zynml/src/lib.rs:199-246
  • RuntimeEngine backend-agnostic enum — zynml/src/lib.rs:141-144
  • AOT pipeline shape — zyntax_cli/src/backends/llvm_aot.rs:103-278 (adapt cc linker step to ar for mobile .a output)

Patterns explicitly rejected: .zrtl plugin discovery from disk (Blinc statically links), env-var runtime profile dispatch, "find first function" entry-point heuristic, REPL.


Phase 4: Rendering & GPU

Goal: Complete the rendering pipeline for advanced visual content.

4.1 3D Mesh Rendering (P1)

FeatureStatusNotes
Generic mesh dataDoneMeshData + Vertex + Material — users convert from glTF/OBJ/FBX
draw_mesh_dataDoneDrawContext::draw_mesh_data(mesh, transform) — direct render, no registration
PBR materialsDoneMaterial: base_color, metallic, roughness, emissive, texture, alpha_mode
Shadow mappingDone2048² depth pass, 4-tap PCF, front-face culling, depth bias
Normal / displacement mapsDoneTangent-space normal maps + parallax occlusion mapping (16-layer)
Skeletal animationDoneBone/Skeleton/SkinningData, GPU skinning via storage buffer (max 256 joints)

4.2 Custom Shaders (P2)

FeatureStatusNotes
Custom render pass APIDoneCustomRenderPass trait, PreRender/PostProcess stages, label-based removal
Custom bind groupsDoneBindGroupBuilder — declarative layout+bind creation for all binding types
Compute shader accessDoneComputeDispatch + create_compute_pipeline() + @flow DAG
Post-processing pipelineDonePostProcessChain — ping-pong effect chain, auto texture management

4.3 Performance (P1)

FeatureStatusNotes
draw_rgba_pixelsDoneDrawContext::draw_rgba_pixels() — GPU texture upload + render per frame
Dynamic image renderingDoneDynamicImage in PrimitiveBatch, renderer uploads + draws via image pipeline
Virtualized list renderingDonevirtual_list() — viewport-aware, variable-height, CSS classes
Texture atlas improvementsDoneSVG atlas, glyph atlas
Lazy image loadingDoneViewport-aware load + 100px buffer, color/image/skeleton placeholders, fade-in animation, CSS loading property
Render region cullingDoneAABB visibility test before GPU upload, shadow/rotation/affine-aware
GPU memory budgetDoneGpuMemoryBudget with LRU eviction, 128 MB default, env var override

4.4 Text & Fonts (P2)

FeatureStatusNotes
Lazy per-codepoint emoji loaderPlannedNetwork-fetched glyph loader for dynamic text — similar to Google Fonts' CSS2 API. Covers runtime strings (user input, fetched content, chat messages) whose codepoints weren't in the build-time emoji subset. Targets web/wasm and non-Apple platforms that don't ship a bundled Color Emoji font. Requires: (1) async FontRegistry::load_glyph_async(codepoint) entry point, (2) a hosted glyph service or a per-codepoint chunked font asset, (3) a pending-glyph placeholder in the shaper so layout doesn't shift when glyphs arrive. Escape hatch for the build-time emoji subsetter (which covers statically-known strings).

Phase 5: Developer Experience

Goal: Make Blinc a joy to develop with.

5.1 Tooling (P1)

FeatureStatusNotes
Hot reloadPlannedFile watcher + incremental rebuild
Visual inspectorPartialblinc_debugger exists, needs UI overlay
Animation debuggerPlannedTimeline view, pause/step
Layout debuggerPlannedFlexbox visualization (like browser devtools)
Performance profilerPlannedFrame time, GPU utilization, batch count

5.2 IDE Integration (P2)

FeatureStatusNotes
VS Code extensionPlannedZyntax syntax highlighting + preview
LSP for .blinc filesPlannedAutocomplete, diagnostics
Component previewPlannedInline rendering in editor
Code snippetsPlannedCommon patterns and widgets

5.3 Documentation (P1)

FeatureStatusNotes
Blinc BookPartialCore concepts, 3D rendering, flow shaders (vertex/material), routing, media
API reference (rustdoc)PartialMany crates need doc improvements
Interactive examplesDone40+ live WebGPU demos in mdBook gallery, auto-generated from cross-target examples
Video tutorialsPlannedGetting started, advanced topics
Skills.md (AI agents)DoneExample-driven reference for LLMs

Phase 6: Accessibility

Goal: Make Blinc apps usable by everyone.

FeaturePriorityNotes
Semantic element rolesP1Button, heading, list, etc.
Screen reader announcementsP1Platform accessibility APIs
Keyboard navigation (Tab order)P1Focus ring, tab index
ARIA-like attributesP1Label, description, live regions
High contrast modeP2Theme variant
Reduced motionP2Respect OS preference
Text scalingP2Independent of DPI scaling

Phase 7: Platform Expansion

PlatformStatusNotes
macOSStablewgpu (Metal)
WindowsStablewgpu (DX12/Vulkan)
LinuxStablewgpu (Vulkan)
AndroidStablewgpu (Vulkan)
iOSStablewgpu (Metal)
HarmonyOSIn progresswgpu (Vulkan/OpenGL ES)
Web (WASM)Preview (Tier 2)wgpu WebGPU + WebGL2 fallback. Full render pipeline: SDF (split pipelines: core/shadow/3D/notch), text, mesh, @flow, motion, overlays, CSS animations/transitions, blend modes, layer effects. WebGL2 fallback (0.5.1): data texture path replaces storage buffers on GL adapters (Android Chrome, older browsers); VERTEX_STORAGE fallback via instance-stepped vertex buffers; glass and particle rendering pending on WebGL2. Chrome 113+, Edge 113+, Firefox 141+, Safari 18+ (macOS Tahoe), iPhone Safari (iOS 18+), Android Chrome (WebGL2). Text: Arial + FiraCode + JetBrains Mono bundled. Asset preload via fetch(). See docs/web.md.
Embedded (RPi)FutureFramebuffer or Vulkan

Release Milestones

VersionTargetFocusStatus
0.2.0Q2 2026Desktop production readiness — system integration, multi-window, IME, clipboard, DnD, tray, hotkeys, code editor, virtual listComplete
0.3.0Q3 2026Mobile production readiness — gestures, safe area, haptics, navigation/router, deep linking, media (audio/video/camera), native bridgeComplete
0.4.0Q3 2026GPU & rendering — 3D mesh pipeline (PBR, shadows, normal maps, skeletal animation), custom shaders (bind groups, compute, post-processing), render culling, memory budgetComplete (pulled forward from 0.5.0)
0.5.0Q2 2026Web/WASM platform (WebGPU), rich text editor, virtualized list, lazy image loading, mobile soft keyboard + edit menuComplete
0.5.1Q2 2026WebGL2 fallback (data textures, vertex storage fallback), split SDF pipelines, video player fixes (wasm duration/pacing), platform capability detectionComplete
0.6.0Q4 2026Blinc DSL v1 — Zyntax embed, Rust embed API (blinc_dsl::component(path)), JIT hot-reload, P0 grammar surfacePlanned
0.6.1Q1 2027LLVM AOT for mobile — iOS/Android static-lib pipeline, no-JIT compliancePlanned
0.6.2Q1 2027Standalone blinc CLI — blinc init/dev/build for non-Rust users, framework-prebuild CIPlanned
0.7.0Q1 2027Developer experience — hot reload, visual inspector, layout/animation debugger, performance profilerPlanned
0.8.0Q1 2027Accessibility v1 — semantic roles, screen reader, keyboard navigation, ARIA-like attributes, high contrast, reduced motionPlanned
0.9.0Q2 2027Platform expansion — HarmonyOS stableIn progress
1.0.0Q3 2027Stable API, full documentation, Zyntax hot reload + LSP, production certificationPlanned

Contributing

See individual crate READMEs for architecture details. The most impactful areas to contribute:

  1. Missing widgets (Phase 1.4) — date picker, color picker, data grid
  2. Blinc DSL (Phase 3) — Zyntax grammar (grammars/blinc.zyn), zrtl_blinc builtins, Rust embed API, AOT pipeline, standalone CLI
  3. Accessibility (Phase 6) — screen reader, keyboard nav, ARIA
  4. Developer tooling (Phase 5) — hot reload, visual inspector, debugger
  5. Documentation — API docs, tutorials, interactive examples