spark_framework 1.0.0-alpha.1 copy "spark_framework: ^1.0.0-alpha.1" to clipboard
spark_framework: ^1.0.0-alpha.1 copied to clipboard

Lightweight isomorphic SSR framework for Dart with Custom Elements and Declarative Shadow DOM

Spark Framework #

A lightweight, isomorphic SSR web framework for Dart that enables Server-Side Rendering with interactive "islands" of client-side logic using Custom Elements and Declarative Shadow DOM.

Features #

  • HTML-first: Server sends fully formed HTML for instant display.
  • Isomorphic Components: Single Dart file defines both server and client logic.
  • Zero-JS Initial Paint: Uses Declarative Shadow DOM for immediate rendering.
  • Typed CSS: Type-safe, autocompleted styling API (Style.typed).
  • Automatic OpenAPI: Generate OpenAPI specifications directly from your code.
  • DTO Validation: Automatic request body validation using annotations.
  • Multi-Page Architecture: Each route has its own lightweight JavaScript bundle.

Installation #

Add dependencies to your pubspec.yaml:

dependencies:
  spark_framework: ^1.0.0-alpha.1

Install the CLI tool globally:

dart pub global activate spark_cli

CLI Usage #

The spark CLI helps you manage your project lifecycle.

  • Initialize a new project:

    spark init my_app
    
  • Run development server (with hot reload):

    spark dev
    
  • Build for production:

    spark build
    
  • Generate OpenAPI specification:

    spark openapi
    

Quick Start #

1. Create a Component #

Create a reusable component with typed styling and isomorphic logic.

import 'package:spark_framework/spark.dart';

part 'counter.g.dart';

@Component(tag: Counter.tag)
class Counter extends SparkComponent with _\$CounterSync {
  Counter({this.count = 0, this.label = 'Count'});

  static const tag = 'my-counter';

  @override
  String get tagName => tag;

  @Attribute(observable: true)
  int count;

  String label;

  @override
  Element build() {
    return div([
      style([
        css({
          ':host': .typed(
            display: .inlineBlock,
            padding: .all(.px(16)),
            border: CssBorder(
              width: .px(1),
              style: .solid,
              color: .hex('#ccc'),
            ),
            borderRadius: .px(8),
            fontFamily: .raw('sans-serif'),
          ),
          'button': .typed(
            cursor: .pointer,
            padding: .symmetric(vertical: .px(4), horizontal: .px(8)),
            margin: .symmetric(horizontal: .px(4)),
          ),
        }).toCss(),
      ]),
      span([label, ': ']),
      span(id: 'val', [count]),
      button(
        id: 'inc',
        onClick: (_) {
          count++;
        },
        ['+'],
      ),
      button(
        id: 'dec',
        onClick: (_) {
          count--;
        },
        ['-'],
      ),
    ]);
  }
}

3. Server Route #

Serve your component using a Shelf handler.

import 'package:spark_framework/spark.dart';
import 'package:spark_framework/server.dart';
import 'package:your_package_name/spark_router.g.dart';

void main() async {
  final server = await createSparkServer(
    SparkServerConfig(
      port: 8080,
    ),
  );
  print('Server running at http://localhost:\${server.port}');
}

Core Concepts #

Styling with Typed CSS #

Spark provides a type-safe API for writing CSS, reducing errors and providing autocomplete.

final myStyle = Style.typed(
  width: CssLength.percent(100),
  height: CssLength.vh(100),
  display: CssDisplay.grid,
  gridTemplateColumns: 'repeat(3, 1fr)', // Complex values can still use strings
  gap: CssLength.rem(2),
  margin: CssSpacing.symmetric(
    vertical: CssLength.px(20),
    horizontal: CssLength.px(0),
  ),
  color: CssColor.rgb(50, 50, 50),
);

Endpoints & Validation #

Define robust API endpoints with automatic validation and documentation.

@Endpoint(path: '/api/users', method: 'POST')
class CreateUser extends SparkEndpoint<CreateUserDto> {
  @override
  Future<Response> handler(SparkRequest req, CreateUserDto body) async {
    // body is automatically validated and typed
    return Response.ok({'id': 123, 'name': body.name});
  }
}

class CreateUserDto {
  @NotEmpty(message: 'Name is required')
  @Length(min: 2, max: 50)
  final String name;

  @Email()
  final String email;

  CreateUserDto({required this.name, required this.email});
}

Validation Annotations #

Supported annotations include:

  • @NotEmpty, @Length, @Min, @Max
  • @Email, @Pattern, @IsNumeric, @IsBooleanString

Project Structure #

A typical Spark project looks like this:

my_app/
├── bin/
│   └── server.dart      # Server entry point
├── lib/
│   ├── components/      # Isomorphic components
│   ├── endpoints/       # API endpoints
│   └── pages/           # Page layouts
├── web/
│   └── main.dart        # Browser entry points
├── pubspec.yaml
└── README.md

License #

MIT

0
likes
0
points
73
downloads

Publisher

verified publisherkleak.dev

Weekly Downloads

Lightweight isomorphic SSR framework for Dart with Custom Elements and Declarative Shadow DOM

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

http_parser, meta, mime, shelf, shelf_router, web

More

Packages that depend on spark_framework