Skip to content

formspec-kotlin: Jetpack Compose renderer for Android #6

Description

@mikewolfd

Motivation

Android apps need to render formspec forms as native Jetpack Compose UI. A Kotlin package mirroring formspec-swift's architecture — hidden Android WebView bridge, Compose-native state, composable component map — provides full spec compliance without reimplementing the engine in Kotlin.

Architecture

Three layers (mirrors formspec-swift):

  1. Bridge — Hidden Android WebView loads the same HTML bundle as Swift (shared packages/formspec-bridge/). Kotlin sends EngineCommand JSON via evaluateJavascript(), receives EngineEvent JSON via @JavascriptInterface.
  2. State@Stable classes (FieldState, FormState) backed by Compose mutableStateOf() / StateFlow. @Immutable on LayoutNode.
  3. RendererFormspecForm composable walks the LayoutNode tree. Component map (Map<String, @Composable (FieldState) -> Unit>) provides default Material 3 components, overridable by the consumer.

Scope

  • Kotlin package (Maven: org.formspec:formspec-kotlin)
  • Android API 26+ minimum (WebView WASM support, onRenderProcessGone)
  • Compose 1.5+ / Compose BOM 2024+
  • Hidden Android WebView bridge sharing HTML bundle with Swift
  • @Stable/@immutable state objects with Compose snapshot integration
  • Auto-renderer with Material 3 default components
  • ProGuard consumer-rules.pro for @JavascriptInterface
  • NOT KMP/Compose Multiplatform (Rust WASM is the shared layer; platform binding is ~500 lines)

Status

ADR accepted (0053). No implementation yet.

Key References

  • ADR: thoughts/adr/0053-formspec-kotlin.md
  • Swift design spec (architecture model): thoughts/specs/2026-03-25-formspec-swift-design.md

Key Decisions (from ADR 0053)

  • Separate Kotlin package, not KMP — platform WebView binding is minimal
  • API 26+ for WASM WebView support
  • Shared HTML bundle from formspec-bridge
  • Lifecycle-aware: bridge tied to ViewModel, survives config changes
  • ProGuard rules required for JS interface

Acceptance Criteria

  • Kotlin package builds and publishes to Maven local
  • Hidden Android WebView bridge initializes formspec-engine and processes commands
  • Compose state objects update reactively from engine events
  • Auto-renderer produces native Compose UI from a formspec definition
  • Component map is overridable by consumers
  • Test suite covers bridge, state, and renderer layers
  • ProGuard consumer-rules.pro included

Part of #4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions