Lark is a Dart web framework with:
- file-based routing
- fine-grained reactivity (
ref,computed,effect) - composables for async/data/storage
- static pre-rendering (SSG)
- server-side rendering (SSR)
- a built-in CLI for scaffolding, dev, and production builds
Lark is not available for external code contributions as at now.
All development happens privately and is implemented internally by automated AI agents.
Use this repository to:
-
Report bugs
-
Request features
-
Track fixes and releases
For documentation and guides: https://larkstack.com
dart pub add larkCreate a project:
dart run lark create my_app
cd my_app
dart pub get
lark devOpen http://localhost:3000.
lib/app.dart:
import 'package:lark/lark.dart';
import 'routes.g.dart';
final app = LarkApp(
routes: routes,
config: const LarkConfig(name: 'My App'),
head: const Head(title: 'My App'),
);web/main.dart:
import 'package:lark/lark.dart';
import 'package:my_app/app.dart';
void main() {
createApp(app).mount('#app');
}Set the Tailwind strategy in lib/app.dart (defaults to selector mode):
final config = LarkConfig(
name: 'My App',
tailwind: TailwindConfig(darkMode: DarkMode.selector),
);Use dark: classes in UI and control preference with useDarkMode():
final theme = useDarkMode();
theme.toggle(); // switch dark/light
theme.setSystem(); // follow OS preferenceOn web, Lark automatically wires storage and system preference detection when the app mounts.
import 'package:lark/lark.dart';
class CounterPage extends Component {
final count = ref(0);
late final doubled = computed(() => count() * 2);
@override
Component build() {
return Column([
Text('Count: ${count()}'),
Text('Doubled: ${doubled()}'),
Button(label: 'Increment', onPressed: () => count.value++),
]);
}
}Lark generates lib/routes.g.dart from lib/pages:
lib/pages/index.dart->/lib/pages/about.dart->/aboutlib/pages/blog/__slug__/index.dart->/blog/:slug
Routes are regenerated by lark dev, lark build, and lark codegen.
useRouter()forpush,replace,back,forward,gouseRoute()for current path/params/query/meta/datauseParams()anduseQueryParams()helpersRouterLinkfor SPA navigationRouterOutletfor nested route trees
final useCounterStore = defineStore('counter', () {
final count = ref(0);
final doubled = computed(() => count() * 2);
void increment() => count.value++;
return (count: count, doubled: doubled, increment: increment);
});final form = useForm({
'email': field(validators: [required, email]),
'password': field(validators: [required, minLength(8)]),
});useFetch,useLazyFetch,usePostusePagination,useInfiniteScroll,useAsync,usePollinguseToggle,useDebounce,useThrottle,usePrevioususeLocalStorage,useSessionStorage,useCookie,useDarkModeuseQuery,useMutation,useLazyQuery
useMeta(...)useSeo(...)useHead([...])- app-level
Head(...)onLarkApp
Put content files in lib/content (.md, .yaml, .json) and run codegen.
Generated catalog: lib/content/content.g.dart
final posts = await content.query('blog').search('dart').find();
final one = await content.findOne('my-post-slug');lark create <name>
lark dev [--port] [--verbose] [--ssr]
lark build [--wasm | --js]
lark start
lark serve [--port] [--host] [--dir]
lark generate <component|page|store> <name>
lark codegen
lark doctor
lark clean
lark tailwind setup
lark buildDeploy build/ to static hosting.
Local check:
lark servelark build also compiles an SSR server binary:
lark build
lark startlark start runs build/server (host/port from args or .env).
For source-mode SSR in environments with Dart installed:
cd build
dart pub get
dart run bin/server.dartUse smaller entrypoints when needed:
package:lark/core.dartpackage:lark/router.dartpackage:lark/store.dartpackage:lark/seo.dartpackage:lark/composables.dartpackage:lark/ssr.dartpackage:lark/web.dart