Sip is a command-line tool that simplifies managing Dart and Flutter projects. It helps you run scripts, manage pub commands, execute tests, and more — all from a single configuration file.
-
Define and run scripts from a
scripts.yamlfile- Supports nested scripts
- Run scripts concurrently
-
Run pub commands (
pub get,pub upgrade, etc.)- Runs recursively and concurrently
-
Run Dart/Flutter tests
- Recursive mode
- Fail fast mode (stops running tests after the first failure)
- Run only Dart or only Flutter tests
-
Customize executable commands (
dart,flutter, etc.)
dart pub global activate sip_clisip --helpCreate a scripts.yaml file in your project root:
# scripts.yaml
hello:
world: echo "Hello, World!"Run your script:
sip run hello worldThe scripts.yaml file defines all scripts and configuration for Sip. It usually lives in your project root.
Sip uses dart and flutter by default. To override them:
(executables):
dart: fvm dart
flutter: fvm flutterA script maps a key to a command:
build_runner: dart run build_runner buildsip run build_runnerCommands can also be lists:
build_runner:
- cd packages/core && dart run build_runner build
- cd packages/data && dart run build_runner build- Allowed pattern:
^_?([a-z][a-z0-9_.\-]*)?(?<=[a-z0-9_])$ - Keys wrapped in parentheses (e.g.,
(command)) are reserved - Must start with a letter or
_ - Must end with a letter, number, or
_
You can nest scripts:
format:
ui: cd packages/ui && dart format .
core: cd packages/core && dart format .Use (command) to specify a default command for the top level script itself:
format:
(command): dart format .
ui: cd packages/ui && dart format .
core: cd packages/core && dart format .sip list # or sip lsSearch:
sip list build_runnerTo explore nested scripts, you can use the --help flag:
sip run build_runner --helpUse ${{ key }} to reference another script:
pub_get: dart pub get
pub_get_ui: cd packages/ui && ${{ pub_get }}References work with nesting:
pub:
(command): dart pub
get: "${{ pub }} get"
ui: cd packages/ui && ${{ pub.get }}Sip forwards only the flags and arguments you explicitly include using ${{ --FLAG_NAME }}:
test: dart test ${{ --coverage }}Examples:
sip run test --coverage=coverage
sip run other --flag value1 value2 --verboseUnspecified flags are ignored.
Private keys (starting with _) cannot be run directly, but can be referenced:
format:
_hidden: dart format .
(command): cd packages/ui && ${{ format._hidden }}Use --bail to stop running as soon as a command fails:
sip run format --bailOr set it in config:
format:
(bail):
(command): dart formatRun scripts concurrently using (+):
format:
(command):
- echo "Running format"
- (+) cd packages/ui && dart format .
- (+) cd packages/core && dart format .
- echo "Finished running format"You can disable concurrency by passing the --no-concurrent flag.
sip run format --no-concurrentSip provides built-in variables:
${{ packageRoot }}: The nearestpubspec.yamlto the current working directory${{ scriptsRoot }}: The nearestscripts.yamlto the current working directory${{ cwd }}: The current working directory${{ dartOrFlutter }}: Eitherdartorflutterexecutable, depending on the nearestpubspec.yamlto the current working directory${{ dart }}: Thedartexecutable${{ flutter }}: Theflutterexecutable
Define custom variables under (variables):
(variables):
ocarinaTune: |-
echo "Playing Song of Time..."Use them:
play: ${{ ocarinaTune }}(variables):
flutter: fvm flutter
build_runner:
build: dart run build_runner build
watch:
(description): Run build_runner in watch mode
(command): dart run build_runner watch
(aliases): [w]
test:
(command): "${{ flutter }} test ${{ --coverage }}"
coverage: "${{ test }} --coverage=coverage"
echo:
dirs:
- echo "${{ packageRoot }}"
- echo "${{ scriptsRoot }}"
- echo "${{ cwd }}"
format:
_command: dart format .
(command):
- echo "Running format"
- (+) ${{ format.ui }}
- (+) ${{ format.data }}
- (+) ${{ format.application }}
- echo "Finished running format"
ui: cd packages/ui && ${{ format._command }}
data: cd packages/data && ${{ format._command }}
application: cd application && ${{ format._command }}Sip always executes from the directory containing your scripts.yaml, regardless of your current working directory.
sip run build_runner buildRun sip run --help for all available flags.
You can load environment variables before running a script:
build:
(command): flutter build apk
(env): .env # or ['.env', '.env.local']Or run a command to generate env vars:
(env):
file: .env # or ['.env', '.env.local']
command: dart run generate_env.dart # can be a list of commandsOr inline variables:
(env):
vars:
FLUTTER_BUILD_MODE: releaseParent script env overrides nested script env.
Use --never-exit to restart a command whenever it fails:
sip run build_runner watch --never-exitWarning
Use with caution — the command restarts indefinitely.
You can stop the script by pressing Ctrl + C.
There is a 1 second delay between each run of the command, to prevent any runaway scripts.
Run all tests:
sip test --recursiveDart-only:
sip test --dart-onlyFlutter-only:
sip test --flutter-onlyFail fast:
sip test --bailsip pub getAutomatically detects whether to use dart or flutter.
Recursive:
sip pub get --recursivesip pub upgradeUpgrade all or specific packages:
sip pub upgrade provider shared_preferencessip pub downgradesip pub deps --jsonConstrain versions to your current resolution:
sip pub constrainConstrain only selected packages:
sip pub constrain provider shared_preferences:2.3.0Pin versions:
sip pub constrain provider --pinUnpin:
sip pub constrain provider --no-pinSupported flags:
recursivedev_dependenciesbump(breaking,major,minor,patch)dry-rundart-onlyflutter-onlypinno-pin
