diff --git a/.github/workflows/very_good_dart_cli_hooks.yaml b/.github/workflows/very_good_dart_cli_hooks.yaml
new file mode 100644
index 0000000..1eb9f42
--- /dev/null
+++ b/.github/workflows/very_good_dart_cli_hooks.yaml
@@ -0,0 +1,21 @@
+name: very_good_dart_cli_hooks
+
+on:
+  pull_request:
+    paths:
+      - ".github/workflows/very_good_dart_cli_hooks.yaml"
+      - "brick/hooks/**"
+  push:
+    branches:
+      - main
+    paths:
+      - ".github/workflows/very_good_dart_cli_hooks.yaml"
+      - "brick/hooks/**"
+
+jobs:
+  build:
+    uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/dart_package.yml@v1
+    with:
+      working_directory: "brick/hooks"
+      analyze_directories: "test"
+      report_on: "post_gen.dart"
diff --git a/brick/hooks/.gitignore b/brick/hooks/.gitignore
new file mode 100644
index 0000000..7b37acf
--- /dev/null
+++ b/brick/hooks/.gitignore
@@ -0,0 +1,4 @@
+.dart_tool
+.packages
+pubspec.lock
+build
diff --git a/brick/hooks/analysis_options.yaml b/brick/hooks/analysis_options.yaml
new file mode 100644
index 0000000..799268d
--- /dev/null
+++ b/brick/hooks/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:very_good_analysis/analysis_options.5.1.0.yaml
diff --git a/brick/hooks/post_gen.dart b/brick/hooks/post_gen.dart
new file mode 100644
index 0000000..b9f038b
--- /dev/null
+++ b/brick/hooks/post_gen.dart
@@ -0,0 +1,30 @@
+import 'dart:io';
+
+import 'package:mason/mason.dart';
+import 'package:meta/meta.dart';
+
+/// Type definition for [Process.run].
+typedef RunProcess = Future<ProcessResult> Function(
+  String executable,
+  List<String> arguments, {
+  String? workingDirectory,
+  bool runInShell,
+});
+
+Future<void> run(
+  HookContext context, {
+  @visibleForTesting RunProcess runProcess = Process.run,
+}) async {
+  // Some imports are relative to the user specified package name, hence
+  // we try to fix the import directive ordering after the template has
+  // been generated.
+  //
+  // We only fix for the [directives_ordering](https://dart.dev/tools/linter-rules/directives_ordering)
+  // linter rules, as the other rule should be tackled by the template itself.
+  await runProcess('dart', [
+    'fix',
+    Directory.current.path,
+    '--apply',
+    '--code=directives_ordering',
+  ]);
+}
diff --git a/brick/hooks/pubspec.yaml b/brick/hooks/pubspec.yaml
new file mode 100644
index 0000000..7f7f614
--- /dev/null
+++ b/brick/hooks/pubspec.yaml
@@ -0,0 +1,13 @@
+name: very_good_dart_cli_hooks
+
+environment:
+  sdk: ">=2.12.0 <3.0.0"
+
+dependencies:
+  mason: ">=0.1.0-dev.51 <0.1.0"
+  meta: ^1.11.0
+
+dev_dependencies:
+  mocktail: ^1.0.0
+  test: ^1.19.2
+  very_good_analysis: ^5.1.0
diff --git a/brick/hooks/test/post_gen_test.dart b/brick/hooks/test/post_gen_test.dart
new file mode 100644
index 0000000..5da6c12
--- /dev/null
+++ b/brick/hooks/test/post_gen_test.dart
@@ -0,0 +1,93 @@
+import 'dart:io';
+
+import 'package:mason/mason.dart';
+import 'package:mocktail/mocktail.dart';
+import 'package:test/test.dart';
+
+import '../post_gen.dart' as post_gen;
+
+class _MockHookContext extends Mock implements HookContext {}
+
+class _MockProcessResult extends Mock implements ProcessResult {}
+
+void main() {
+  group('post_gen', () {
+    late HookContext context;
+    late ProcessResult processResult;
+    late List<Invocation> invocations;
+
+    setUp(() {
+      context = _MockHookContext();
+      processResult = _MockProcessResult();
+      invocations = [];
+    });
+
+    Future<ProcessResult> runProcess(
+      String executable,
+      List<String> arguments, {
+      String? workingDirectory,
+      bool runInShell = false,
+    }) async {
+      final positionalArguments = [executable, arguments];
+      final namedArguments = {
+        const Symbol('workingDirectory'): workingDirectory,
+        const Symbol('runInShell'): runInShell,
+      };
+      final invocation = Invocation.method(
+        const Symbol('runProcess'),
+        positionalArguments,
+        namedArguments,
+      );
+      invocations.add(invocation);
+
+      return processResult;
+    }
+
+    test('fixes `directives_ordering` Dart linter rule', () async {
+      await post_gen.run(context, runProcess: runProcess);
+
+      expect(invocations, contains(_IsDartDirectiveOrderingFix()));
+    });
+  });
+}
+
+Matcher isDartDirectiveOrderingFix() {
+  return _IsDartDirectiveOrderingFix();
+}
+
+class _IsDartDirectiveOrderingFix extends Matcher {
+  @override
+  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
+    if (item is! Invocation) {
+      return false;
+    }
+
+    final invocation = item;
+    final executableName = invocation.positionalArguments[0] as String;
+    final arguments = invocation.positionalArguments[1] as List<String>;
+    final workingDirectory =
+        invocation.namedArguments[const Symbol('workingDirectory')] as String?;
+
+    return executableName == 'dart' &&
+        arguments.contains('fix') &&
+        arguments.contains(Directory.current.path) &&
+        arguments.contains('--apply') &&
+        arguments.contains('--code=directives_ordering') &&
+        workingDirectory == null;
+  }
+
+  @override
+  Description describe(Description description) {
+    return description.add('is a Dart fix for directives_ordering');
+  }
+
+  @override
+  Description describeMismatch(
+    dynamic item,
+    Description mismatchDescription,
+    Map<dynamic, dynamic> matchState,
+    bool verbose,
+  ) {
+    return mismatchDescription.add('is not a Dart fix for directives_ordering');
+  }
+}