neon_mobile_framework/replit.md
2026-02-19 05:44:08 +03:00

8.6 KiB

Neon Framework

Overview

Neon Framework is a custom Dart-based UI framework for building native mobile apps (Android & iOS) without any Flutter dependency. It is a standalone SDK that owns its own runtime, widget system, rendering pipeline, state management, and platform bridges. The framework communicates with native apps via an HTTP-based bridge — the Dart backend runs a local HTTP server that serves a JSON widget tree, and native apps (Android/iOS) fetch this tree, render native UI components, and send user actions back via POST requests.

The project has completed 8 development phases: Vision → Core Runtime → Widget System → Rendering Layer → State Management → Platform Layer → Tooling (CLI) → Storage & Networking → Plugins & Extensibility.

The main framework code lives in neon_framework/ and a test app lives in neon_framework/my_2nd_test_app/ with both Android (Kotlin) and iOS (Swift) native shells.

User Preferences

Preferred communication style: Simple, everyday language.

System Architecture

Core Framework (neon_framework/lib/src/)

The framework follows a layered architecture:

  1. Core Runtime (core/): NeonApp.run() entry point, lifecycle management (onInit, onPause, onResume, onDispose, onHotReload), environment-aware error handling, and configuration via NeonConfig, NeonBuildFlavor, and NeonFeatureFlags.

  2. Widget System (widgets/): Inspired by Flutter's composition model. Includes NeonWidget, StatelessWidget, StatefulWidget, and NeonState. Widgets build a tree (NeonWidgetTree / NeonElement) and serialize to JSON for native rendering. Includes primitives (Text, Button, Container) and layouts (Column, Row, Stack). Material 3 widgets (Switch, Checkbox, Radio, Slider, Chips, Badge, Card, Dialog, BottomSheet, TextField, SearchBar, SearchAnchor, MenuAnchor, MenuBar) are also supported.

  3. Rendering Layer (rendering/): Custom layout engine with constraints, render objects, canvas abstractions, and a render pipeline (Layout → Paint → Composite). Includes animation foundations with curves and spring physics.

  4. State Management (state/): Reactive primitives — NeonSignal (observable values), NeonComputed (derived values), NeonEffect (side effects), and NeonAsyncValue (loading/success/error/cached states). setState() triggers widget tree rebuilds and re-serialization.

  5. Data Layer (storage/, networking/): Key-value store, SQLite database with migrations, HTTP client with interceptors, WebSocket client with auto-reconnect, and a cache policy system (cache-first, network-first, stale-while-revalidate, etc.).

  6. Plugin System (plugins/): Dual-mode architecture supporting Dart-only and native plugins. Includes a plugin registry with dependency resolution, capability conflict detection, lifecycle management, and a hook system. Semantic versioning and SDK constraints are enforced.

  7. CLI Tooling (bin/neon.dart, tooling/): Commands for create, run, build, doctor, clean. Hot reload engine with file watching, debounce, and three reload tiers (UI-only, state-preserving, full).

Platform Bridge Architecture

This is the most important architectural pattern to understand:

  • Dart side runs an HTTP server (typically on localhost:8080)
  • GET / returns the full widget tree as JSON
  • POST /action receives user interactions (widget ID, index, value) and returns the updated widget tree as JSON
  • Native apps (Android MainActivity.kt, iOS ViewController.swift) fetch the JSON tree, recursively render native UI components, and send actions back when users interact
  • State updates flow: User taps → native sends POST → Dart finds widget by ID → calls callback → setState() → tree rebuilds → new JSON sent back → native re-renders

Key Design Decisions

  • No Flutter: This is intentional. The framework owns its entire stack. Don't add Flutter dependencies.
  • JSON-based rendering: Widgets serialize to JSON maps. The native side interprets these maps to create native Android/iOS views. This is the bridge between Dart logic and native UI.
  • Widget keys: Interactive widgets must have stable string keys so the native apps can target them for action events. Missing keys was a recurring bug source.
  • double.infinity handling: JSON doesn't support infinity values. These must be clamped or replaced before serialization.
  • Microtask timing: setState() is async — the action handler must await Future.delayed(Duration.zero) before rebuilding the tree, to let the microtask queue flush.

Test App Structure

my_2nd_test_app/ contains:

  • lib/ — Dart app code using the Neon Framework (8 screens: Dashboard, Interaction, Controls, Values, Advanced, Containment, Input, Info & Progress)
  • android/ — Gradle-based Android project with MainActivity.kt that renders the JSON widget tree
  • NeonApp/ — Xcode project with ViewController.swift that renders the JSON widget tree on iOS

Recent Changes (Phase 10 - Information & Progress Widgets)

  • Added 8 new Material 3 widget types: ListTile, LinearProgressIndicator, CircularProgressIndicator, Tooltip, SnackBar, SingleChildScrollView, ListView (with builder/separated variants), CustomScrollView with sliver support (SliverList, SliverAppBar)
  • Full JSON serialization, action handling, and HTML/CSS/JS web renderer for all new widgets
  • Native Android (Kotlin) and iOS (Swift) rendering support for all new widgets
  • New Info & Progress showcase screen demonstrating all new widget types
  • Navigation bar expanded to 8 tabs
  • Fixed Radio button generic type crash: added selectValue() method to bypass Dart generic type erasure issue with onChanged callback
  • Previous phase 9 changes preserved: Card, Dialog, BottomSheet, TextField, SearchBar, MenuAnchor/MenuBar
  • Fixed web renderer Button click bug: Container type check was matching before Button check in the JS renderer, preventing buttons (whose type is Container but sourceType is Button) from being clickable. Moved isButton/Button check before Container check. Native renderers (Android/iOS) already handled this via isButton flag.
  • Fixed nested AppBar/NavigationBar rendering: When ShowcaseApp is embedded inside AppLauncher, the AppBar and NavigationBar were nested inside Expanded/ShowcaseApp rather than at root level. Added inline rendering for both widget types in renderWidget() so they display correctly at any nesting depth. Also added NavigationBar, TabBar, and AppBar to the interactable widget list in widget_tree.dart for proper action routing.

Flutter-to-Neon Transpiler (tools/transpiler/)

  • Purpose: Source-to-source converter that transforms Flutter widget code into Neon-compatible code
  • Entry point: tools/transpiler/main.dart — runs before the main app in the workflow
  • Input: Place Flutter .dart files in flutter_input/ directory
  • Output: Converted files go to lib/neon_compat/ with a barrel export neon_compat.dart
  • Widget mapping (tools/transpiler/widget_mapping.dart): Maps ~50 Flutter widgets/types to Neon equivalents
  • Key transformations:
    • Flutter imports → package:neon_framework/neon.dart
    • StatelessWidget/StatefulWidget → Neon base classes
    • State<T>NeonState<T>
    • Widget build(BuildContext)NeonWidget build(NeonBuildContext)
    • ElevatedButtonFilledButton, TextStyleNeonTextStyle, EdgeInsetsNeonEdgeInsets, etc.
    • Key? keyString? key
    • Removes Flutter-specific imports, handles Scaffold removal
  • Usage: dart run tools/transpiler/main.dart [input_dir] [output_dir]
  • Uses: analyzer package for Dart AST parsing to find widget classes

External Dependencies

Dart Packages (from pubspec)

  • analyzer — Dart AST parsing for the transpiler
  • args — CLI argument parsing
  • path — File path manipulation
  • watcher — File system watching for hot reload
  • test (dev) — Unit testing

Native Platform Dependencies

  • Android: Standard Android SDK (API 21+), Kotlin, Gradle. Uses java.net.URL for HTTP communication with the Dart backend. Native widgets include android.widget.Switch, CheckBox, RadioButton, SeekBar, etc.
  • iOS: UIKit-based (not SwiftUI). Uses URLSession for HTTP communication. Native widgets include UISwitch, UIButton, UISlider, etc. Xcode project targets iOS simulator (arm64).

No Database or External Services

The framework includes its own storage abstractions (key-value store, SQLite) with in-memory backends for testing. There is no external database dependency like Postgres. The HTTP client and WebSocket client are built-in with mock backends available.