1# Dart {#sec-language-dart} 2 3## Dart applications {#ssec-dart-applications} 4 5The function `buildDartApplication` builds Dart applications managed with pub. 6 7It fetches its Dart dependencies automatically through `pub2nix`, and (through a series of hooks) builds and installs the executables specified in the pubspec file. The hooks can be used in other derivations, if needed. The phases can also be overridden to do something different from installing binaries. 8 9If you are packaging a Flutter desktop application, use [`buildFlutterApplication`](#ssec-dart-flutter) instead. 10 11`pubspecLock` is the parsed pubspec.lock file. pub2nix uses this to download required packages. 12This can be converted to JSON from YAML with something like `yq . pubspec.lock`, and then read by Nix. 13 14Alternatively, `autoPubspecLock` can be used instead, and set to a path to a regular `pubspec.lock` file. This relies on import-from-derivation, and is not permitted in Nixpkgs, but can be useful at other times. 15 16::: {.warning} 17When using `autoPubspecLock` with a local source directory, make sure to use a 18concatenation operator (e.g. `autoPubspecLock = src + "/pubspec.lock";`), and 19not string interpolation. 20 21String interpolation will copy your entire source directory to the Nix store and 22use its store path, meaning that unrelated changes to your source tree will 23cause the generated `pubspec.lock` derivation to rebuild! 24::: 25 26If the package has Git package dependencies, the hashes must be provided in the `gitHashes` set. If a hash is missing, an error message prompting you to add it will be shown. 27 28The `dart` commands run can be overridden through `pubGetScript` and `dartCompileCommand`; you can also add flags using `dartCompileFlags` or `dartJitFlags`. 29 30Dart supports multiple [outputs types](https://dart.dev/tools/dart-compile#types-of-output); you can choose between them using `dartOutputType` (defaults to `exe`). If you want to override the binaries path or the source path they come from, you can use `dartEntryPoints`. Outputs that require a runtime will automatically be wrapped with the relevant runtime (`dartaotruntime` for `aot-snapshot`, `dart run` for `jit-snapshot` and `kernel`, `node` for `js`); this can be overridden through `dartRuntimeCommand`. 31 32```nix 33{ 34 lib, 35 buildDartApplication, 36 fetchFromGitHub, 37}: 38 39buildDartApplication rec { 40 pname = "dart-sass"; 41 version = "1.62.1"; 42 43 src = fetchFromGitHub { 44 owner = "sass"; 45 repo = "dart-sass"; 46 tag = version; 47 hash = "sha256-U6enz8yJcc4Wf8m54eYIAnVg/jsGi247Wy8lp1r1wg4="; 48 }; 49 50 pubspecLock = lib.importJSON ./pubspec.lock.json; 51} 52``` 53 54### Patching dependencies {#ssec-dart-applications-patching-dependencies} 55 56Some Dart packages require patches or build environment changes. Package derivations can be customised with the `customSourceBuilders` argument. 57 58A collection of such customisations can be found in Nixpkgs, in the `development/compilers/dart/package-source-builders` directory. 59 60This allows fixes for packages to be shared between all applications that use them. It is strongly recommended to add to this collection instead of including fixes in your application derivation itself. 61 62### Running executables from dev_dependencies {#ssec-dart-applications-build-tools} 63 64Many Dart applications require executables from the `dev_dependencies` section in `pubspec.yaml` to be run before building them. 65 66This can be done in `preBuild`, in one of two ways: 67 681. Packaging the tool with `buildDartApplication`, adding it to Nixpkgs, and running it like any other application 692. Running the tool from the package cache 70 71Of these methods, the first is recommended when using a tool that does not need 72to be of a specific version. 73 74For the second method, the `packageRun` function from the `dartConfigHook` can be used. 75This is an alternative to `dart run` that does not rely on Pub. 76 77e.g., for `build_runner`: 78 79```bash 80packageRun build_runner build 81``` 82 83Do _not_ use `dart run <package_name>`, as this will attempt to download dependencies with Pub. 84 85### Usage with nix-shell {#ssec-dart-applications-nix-shell} 86 87#### Using dependencies from the Nix store {#ssec-dart-applications-nix-shell-deps} 88 89As `buildDartApplication` provides dependencies instead of `pub get`, Dart needs to be explicitly told where to find them. 90 91Run the following commands in the source directory to configure Dart appropriately. 92Do not use `pub` after doing so; it will download the dependencies itself and overwrite these changes. 93 94```bash 95cp --no-preserve=all "$pubspecLockFilePath" pubspec.lock 96mkdir -p .dart_tool && cp --no-preserve=all "$packageConfig" .dart_tool/package_config.json 97``` 98 99## Flutter applications {#ssec-dart-flutter} 100 101The function `buildFlutterApplication` builds Flutter applications. 102 103See the [Dart documentation](#ssec-dart-applications) for more details on required files and arguments. 104 105`flutter` in Nixpkgs always points to `flutterPackages.stable`, which is the latest packaged version. To avoid unforeseen breakage during upgrade, packages in Nixpkgs should use a specific flutter version, such as `flutter319` and `flutter322`, instead of using `flutter` directly. 106 107```nix 108{ flutter322, fetchFromGitHub }: 109 110flutter322.buildFlutterApplication { 111 pname = "firmware-updater"; 112 version = "0-unstable-2023-04-30"; 113 114 # To build for the Web, use the targetFlutterPlatform argument. 115 # targetFlutterPlatform = "web"; 116 117 src = fetchFromGitHub { 118 owner = "canonical"; 119 repo = "firmware-updater"; 120 rev = "6e7dbdb64e344633ea62874b54ff3990bd3b8440"; 121 hash = "sha256-s5mwtr5MSPqLMN+k851+pFIFFPa0N1hqz97ys050tFA="; 122 fetchSubmodules = true; 123 }; 124 125 pubspecLock = lib.importJSON ./pubspec.lock.json; 126} 127``` 128 129### Usage with nix-shell {#ssec-dart-flutter-nix-shell} 130 131Flutter-specific `nix-shell` usage notes are included here. See the [Dart documentation](#ssec-dart-applications-nix-shell) for general `nix-shell` instructions. 132 133#### Entering the shell {#ssec-dart-flutter-nix-shell-enter} 134 135By default, dependencies for only the `targetFlutterPlatform` are available in the 136build environment. This is useful for keeping closures small but can be problematic 137during development. It's common, for example, to build Web apps for Linux during 138development to take advantage of native features such as stateful hot reload. 139 140To enter a shell with all the usual target platforms available, use the `multiShell` attribute. 141 142e.g. `nix-shell '<nixpkgs>' -A fluffychat-web.multiShell`.