Skip to content

Getting started

This guide covers two paths: working inside this monorepo (contributing to khflutterlib itself, or exploring the component gallery), and consuming its packages from a separate hackathon app.

Prerequisites

  • Flutter 3.44.1 (stable channel) — this is the exact version pinned in CI (.github/workflows/ci.yml). Other 3.24+ versions may work, but a version mismatch between your local SDK and CI's is what caused a real SemanticsFlags-related test failure earlier in this project (tests passed locally, failed in CI, on two different Flutter versions with slightly different dart:ui behavior). Pin to 3.44.1 to avoid that class of surprise.
  • Dart >=3.9.0 <4.0.0 (ships with the Flutter version above).
  • Melos 7+: dart pub global activate melos.

Working inside this repo

git clone https://github.com/msflib/flutter.git khflutterlib
cd khflutterlib
melos bootstrap

melos bootstrap runs pub get across every package in the workspace (packages/kh_core, packages/kh_theme, packages/kh_ui, packages/kh_screens, packages/kh_utils, packages/example) in parallel.

Run the component gallery to see every kh_ui widget, the kh_screens screens and the kh_utils helpers live:

cd packages/example
flutter run

The gallery is organized by screen: buttons, components, text fields, form controls, cards, chips and badges, dialogs, loading/empty/error states, screens, navigation, validators and formatters. See the example gallery page.

Useful Melos scripts (run from the repo root):

melos run format        # dart format --set-exit-if-changed . (check only)
melos run analyze       # dart analyze --fatal-infos
melos run test          # dart test, for Dart-only packages (kh_core, kh_utils)
melos run test:flutter  # flutter test, for Flutter packages (kh_theme, kh_ui, kh_screens, example)

CI runs these four in this order, after melos run release:check (every internal kh_* git dependency pins the same release-train tag) and melos run generate (Freezed codegen). A clean local run of all six is a strong signal a PR will pass CI.

Golden tests

kh_ui/test/goldens/ renders every widget variant under KhTheme.light() and KhTheme.dark() and compares the result against the PNGs committed in kh_ui/test/goldens/goldens/ci/. They run as part of melos run test:flutter. Text is drawn as solid blocks and shadows as flat fills.

Goldens are generated on Linux only. Skia anti-aliases curved edges (dialog corners, switches, pills) very slightly differently on Windows, macOS and Linux, so PNGs made on a laptop fail on CI by a fraction of a percent. CI's Linux runner is the reference and compares pixel-exactly. Locally, on Windows or macOS, comparisons allow 1% of pixels to differ. That absorbs the platform noise while still catching most real layout changes, but treat CI as the authority. flutter test --update-goldens refuses to run off Linux.

When a widget's appearance changes on purpose, or you add a new golden:

  1. Push your branch. CI's golden tests fail, and the run uploads two artifacts:
  2. kh_ui-golden-failures: diff images showing what changed. Check the change is the one you intended.
  3. kh_ui-goldens-linux: the full set of goldens regenerated on Linux.
  4. Download kh_ui-goldens-linux from the run's summary page, unzip it into packages/kh_ui/test/goldens/goldens/ci/, and commit the PNGs that changed.
  5. Push. CI compares against the Linux PNGs and passes.

If the change isn't intended, the diff images show what moved. Locally, they're written to the failures/ folder next to the failing test (gitignored).

Consuming packages from your own hackathon app

khflutterlib is not published to pub.dev (see PHASE_0_ARCHITECTURE.md §4) — it's private to Kodehauz, so apps depend on it via a git dependency pointing at a path inside the monorepo:

dependencies:
  flutter:
    sdk: flutter
  kh_core:
    git:
      url: https://github.com/msflib/flutter.git
      path: packages/kh_core
      ref: khflutterlib-v0.4.3
  kh_theme:
    git:
      url: https://github.com/msflib/flutter.git
      path: packages/kh_theme
      ref: khflutterlib-v0.4.3
  kh_ui:
    git:
      url: https://github.com/msflib/flutter.git
      path: packages/kh_ui
      ref: khflutterlib-v0.4.3
  kh_screens:
    git:
      url: https://github.com/msflib/flutter.git
      path: packages/kh_screens
      ref: khflutterlib-v0.4.3
  kh_utils:
    git:
      url: https://github.com/msflib/flutter.git
      path: packages/kh_utils
      ref: khflutterlib-v0.4.3

Pin every kh_* package to the same release-train tag, khflutterlib-v<x.y.z>, never a branch. The packages depend on each other through that same tag, and pub refuses two different git refs for one package, so mixing tags (or using the older per-package tags such as kh_core-v0.1.1) makes flutter pub get fail. To upgrade, change every ref together. The release train page lists each release and the package versions it contains.

Also add uses-material-design: true to your own app's pubspec.yaml (under a flutter: key) if you use any kh_ui widget that shows a default icon (KhBadge, KhEmptyState/KhErrorState, KhButton, KhTextField). kh_ui declaring this itself doesn't bundle the font for your app — only your app's own declaration does; Flutter only prints a warning if you forget it, it doesn't fail loudly. Skipping this is exactly what caused every icon in this repo's own example gallery to render as a garbled glyph instead of the intended icon.

Minimal usage — wrap your app in the theme and drop in a widget:

import 'package:flutter/material.dart';
import 'package:kh_theme/kh_theme.dart';
import 'package:kh_ui/kh_ui.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: KhTheme.light(),
      darkTheme: KhTheme.dark(),
      home: Scaffold(
        appBar: AppBar(title: const Text('My hackathon app')),
        // Builder gives the button a context *below* MaterialApp, which
        // KhSnackbar.show needs to find a ScaffoldMessenger. The build
        // method's own context sits above MaterialApp and would throw.
        body: Builder(
          builder: (context) => Center(
            child: KhButton.primary(
              onPressed: () =>
                  KhSnackbar.show(context, content: const Text('Hi!')),
              child: const Text('Say hi'),
            ),
          ),
        ),
      ),
    );
  }
}

The kh_theme page covers the other KhTheme entry points (custom seed color, exact ColorScheme, fonts, shapes, gradients).

What's available today

Only kh_core, kh_theme, kh_ui, kh_screens, kh_utils, and the example gallery app are built so far. Anything else in the root README.md's package table is still planned, not scaffolded, so don't add a git dependency on it. The package pages list what each package exports, and each package's CHANGELOG.md records what changed in each version.

If something doesn't work

This guide was validated against a real clean clone as part of the PR that added it — if you hit something not covered here, it's either genuinely new or the guide is out of date; flag it either way rather than assuming it's just you.