skills/kevmoo/dash_skills/dart-cli-app-best-practices

dart-cli-app-best-practices

SKILL.md

Dart CLI Application Best Practices

1. When to use this skill

Use this skill when:

  • Creating a new Dart CLI application.
  • Refactoring an existing CLI entrypoint (bin/).
  • Reviewing CLI code for quality and standards.
  • Setting up executable scripts for Linux/Mac.

2. Best Practices

Entrypoint Structure (bin/)

Keep the contents of your entrypoint file (e.g., bin/my_app.dart) minimal. This improves testability by decoupling logic from the process runner.

DO:

// bin/my_app.dart
import 'package:my_app/src/entry_point.dart';

Future<void> main(List<String> arguments) async {
  await runApp(arguments);
}

DON'T:

  • Put complex logic directly in bin/my_app.dart.
  • Define classes or heavy functions in the entrypoint.

Executable Scripts

For CLI tools intended to be run directly on Linux and Mac, add a shebang and ensure the file is executable.

DO:

  1. Add #!/usr/bin/env dart to the first line.
  2. Run chmod +x bin/my_script.dart to make it executable.
#!/usr/bin/env dart

void main() => print('Ready to run!');

Process Termination (exitCode)

Properly handle process termination to allow for debugging and correct status reporting.

DO:

  • Use the exitCode setter to report failure.
  • Allow main to complete naturally.
  • Use standard exit codes (sysexits) for clarity (e.g., 64 for bad usage, 78 for configuration errors).
    • See package:io ExitCode class or FreeBSD sysexits man page.
import 'dart:io';

void main() {
  if (someFailure) {
    exitCode = 64; // DO!
    return;
  }
}

AVOID:

  • Calling exit(code) directly, as it terminates the VM immediately, preventing "pause on exit" debugging and finally blocks from running.

Exception Handling

Uncaught exceptions automatically set a non-zero exit code, but you should handle expected errors gracefully.

Example:

Future<void> main(List<String> arguments) async {
  try {
    await runApp(arguments);
  } catch (e, stack) {
    print('App crashed!');
    print(e);
    print(stack);
    exitCode = 1; // Explicitly fail
  }
}

3. Recommended Packages

Use these community-standard packages owned by the Dart team to solve common CLI problems:

Category Recommended Package Usage
Stack Traces package:stack_trace detailed, cleaner stack traces
Arg Parsing package:args standard flag/option parsing
Testing package:test_process integration testing for CLI apps
Testing package:test_descriptor file system fixtures for tests
Networking package:http standard HTTP client (remember user-agent!)
ANSI Output package:io handling ANSI colors and styles

4. Interesting community packages

Category Recommended Package Usage
Configuration package:json_serializable strongly typed config objects
CLI Generation package:build_cli generate arg parsers from classes
Version Info package:build_version automatic version injection
Configuration package:checked_yaml precise YAML parsing with line numbers

5. Conventions

  • File Caching: Write cached files to .dart_tool/[pkg_name]/.
  • User-Agent: Always set a User-Agent header in HTTP requests, including version info.
Weekly Installs
57
GitHub Stars
118
First Seen
Feb 6, 2026
Installed on
antigravity43
opencode23
github-copilot23
codex23
gemini-cli22
amp21