diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart
index 8642fd8..ce00e49 100644
--- a/pkg/modular_test/lib/src/loader.dart
+++ b/pkg/modular_test/lib/src/loader.dart
@@ -111,7 +111,10 @@
   Directory folder = Directory.fromUri(root);
   int baseUriPrefixLength = folder.parent.uri.path.length;
   await for (var file in folder.list(recursive: true)) {
-    sources.add(Uri.parse(file.uri.path.substring(baseUriPrefixLength)));
+    var path = file.uri.path;
+    if (path.endsWith('.dart')) {
+      sources.add(Uri.parse(path.substring(baseUriPrefixLength)));
+    }
   }
   return sources..sort((a, b) => a.path.compareTo(b.path));
 }
diff --git a/pkg/modular_test/lib/src/suite.dart b/pkg/modular_test/lib/src/suite.dart
index e5f17a4..a96e8c8 100644
--- a/pkg/modular_test/lib/src/suite.dart
+++ b/pkg/modular_test/lib/src/suite.dart
@@ -15,6 +15,8 @@
 
   ModularTest(this.modules, this.mainModule)
       : assert(mainModule != null && modules.length > 0);
+
+  String debugString() => modules.map((m) => m.debugString()).join('\n');
 }
 
 /// A single module in a modular test.
@@ -60,6 +62,17 @@
 
   @override
   String toString() => '[module $name]';
+
+  String debugString() {
+    var buffer = new StringBuffer();
+    buffer.write('   ');
+    buffer.write(name);
+    buffer.write(': ');
+    buffer.write(isPackage ? 'package' : '(not package)');
+    buffer.write(', deps: {${dependencies.map((d) => d.name).join(", ")}}');
+    buffer.write(', sources: {${sources.map((u) => "$u").join(', ')}}');
+    return '$buffer';
+  }
 }
 
 final RegExp _validModuleName = new RegExp(r'^[a-zA-Z_][a-zA-Z0-9_]*$');
diff --git a/pkg/modular_test/test/loader/valid_packages/expectation.txt b/pkg/modular_test/test/loader/valid_packages/expectation.txt
index 3c0888d..dab4163 100644
--- a/pkg/modular_test/test/loader/valid_packages/expectation.txt
+++ b/pkg/modular_test/test/loader/valid_packages/expectation.txt
@@ -12,7 +12,6 @@
   (no dependencies)
   lib/js.dart
   lib/js_util.dart
-  lib/src/
   lib/src/varargs.dart
 
 main
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 3df3488..84af435 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -30,6 +30,7 @@
 model/native_test: Pass, Slow
 model/no_such_method_enabled_test: Pass, Slow
 model/subtype_test: Pass, Slow
+modular/*: Slow, Pass
 packages/*: Skip # Skip packages folder
 rti/rti_emission_test: Pass, Slow
 rti/rti_need0_test: Pass, Slow
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/def.dart b/tests/compiler/dart2js/modular/data/int_js_number/def.dart
new file mode 100644
index 0000000..0fd7377
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/def.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+const int foo = 331;
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/main.dart b/tests/compiler/dart2js/modular/data/int_js_number/main.dart
new file mode 100644
index 0000000..6352c3d
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/main.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'def.dart';
+
+main() {
+  print(const <int>[foo]);
+}
diff --git a/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml b/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml
new file mode 100644
index 0000000..a02b69a
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/int_js_number/modules.yaml
@@ -0,0 +1,8 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Regression test: integral numbers should be treated as int and not double
+# after serialization across modules.
+dependencies:
+  main: def
diff --git a/tests/compiler/dart2js/modular/data/package_imports/.packages b/tests/compiler/dart2js/modular/data/package_imports/.packages
new file mode 100644
index 0000000..3da0bf2
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/.packages
@@ -0,0 +1,6 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+f0:.
+f1:.
+a:a
diff --git a/tests/compiler/dart2js/modular/data/package_imports/a/a.dart b/tests/compiler/dart2js/modular/data/package_imports/a/a.dart
new file mode 100644
index 0000000..3a62c13
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/a/a.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'package:f1/f1.dart';
+
+int z = y + 100;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f0.dart b/tests/compiler/dart2js/modular/data/package_imports/f0.dart
new file mode 100644
index 0000000..27b7873
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f0.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+int x = 1;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f1.dart b/tests/compiler/dart2js/modular/data/package_imports/f1.dart
new file mode 100644
index 0000000..0eeb9f8
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f1.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'package:f0/f0.dart';
+
+int y = x + 10;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/f3.dart b/tests/compiler/dart2js/modular/data/package_imports/f3.dart
new file mode 100644
index 0000000..72965f8
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/f3.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'package:a/a.dart';
+
+int w = z + 1000;
diff --git a/tests/compiler/dart2js/modular/data/package_imports/main.dart b/tests/compiler/dart2js/modular/data/package_imports/main.dart
new file mode 100644
index 0000000..7dcee7a
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/main.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'f3.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  print(w);
+  Expect.isTrue(w == 1111);
+}
diff --git a/tests/compiler/dart2js/modular/data/package_imports/modules.yaml b/tests/compiler/dart2js/modular/data/package_imports/modules.yaml
new file mode 100644
index 0000000..a8731e9
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/package_imports/modules.yaml
@@ -0,0 +1,13 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Test ensuring that the modular compiler works properly with `package:`
+# imports. This test also ensures that the dart2js implementation of the modular
+# test pipeline works as intended. The test is not designed to cover any
+# compiler or language feature explicitly.
+dependencies:
+  main: [f3, expect]
+  f3: a
+  a: f1
+  f1: f0
diff --git a/tests/compiler/dart2js/modular/data/subclass/a/a.dart b/tests/compiler/dart2js/modular/data/subclass/a/a.dart
new file mode 100644
index 0000000..e393550
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/a/a.dart
@@ -0,0 +1,4 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+const x = 1;
diff --git a/tests/compiler/dart2js/modular/data/subclass/f0.dart b/tests/compiler/dart2js/modular/data/subclass/f0.dart
new file mode 100644
index 0000000..113a6ff
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/f0.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+class A0 {
+  StringBuffer buffer = new StringBuffer()..write("hello ");
+}
diff --git a/tests/compiler/dart2js/modular/data/subclass/f1.dart b/tests/compiler/dart2js/modular/data/subclass/f1.dart
new file mode 100644
index 0000000..00f7709
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/f1.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'f0.dart';
+
+class B1 extends A0 {
+  A0 get foo => null;
+}
+
+A0 createA0() => new A0();
diff --git a/tests/compiler/dart2js/modular/data/subclass/main.dart b/tests/compiler/dart2js/modular/data/subclass/main.dart
new file mode 100644
index 0000000..090de94
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/main.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+import 'f1.dart';
+import 'a/a.dart';
+
+class C2 extends B1 {
+  final foo = createA0();
+}
+
+main() {
+  var buffer = new C2().foo.buffer;
+
+  buffer.write('world! $x');
+  print(buffer.toString());
+}
diff --git a/tests/compiler/dart2js/modular/data/subclass/modules.yaml b/tests/compiler/dart2js/modular/data/subclass/modules.yaml
new file mode 100644
index 0000000..70606e9
--- /dev/null
+++ b/tests/compiler/dart2js/modular/data/subclass/modules.yaml
@@ -0,0 +1,9 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+#
+# Test illustrating how the modular pipeline works. This test is not designed to
+# stress any specific feature of the compiler.
+dependencies:
+  f1: f0
+  main: [f1, a]
diff --git a/tests/compiler/dart2js/modular/modular_test.dart b/tests/compiler/dart2js/modular/modular_test.dart
new file mode 100644
index 0000000..b28edbf
--- /dev/null
+++ b/tests/compiler/dart2js/modular/modular_test.dart
@@ -0,0 +1,295 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Test the modular compilation pipeline of dart2js.
+///
+/// This is a shell that runs multiple tests, one per folder under `data/`.
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+import 'package:modular_test/src/io_pipeline.dart';
+import 'package:modular_test/src/loader.dart';
+import 'package:modular_test/src/pipeline.dart';
+import 'package:modular_test/src/suite.dart';
+
+_Options _options;
+main(List<String> args) {
+  _options = _Options.parse(args);
+  asyncTest(() async {
+    var baseUri = Platform.script.resolve('data/');
+    var baseDir = Directory.fromUri(baseUri);
+    await for (var entry in baseDir.list(recursive: false)) {
+      if (entry is Directory) {
+        await _runTest(entry.uri, baseUri);
+      }
+    }
+  });
+}
+
+Future<void> _runTest(Uri uri, Uri baseDir) async {
+  var dirName = uri.path.substring(baseDir.path.length);
+  if (_options.filter != null && !dirName.contains(_options.filter)) {
+    if (_options.showSkipped) print("skipped: $dirName");
+    return;
+  }
+
+  print("testing: $dirName");
+  ModularTest test = await loadTest(uri);
+  if (_options.verbose) print(test.debugString());
+  var pipeline = new IOPipeline([
+    SourceToDillStep(),
+    CompileFromDillStep(),
+    RunD8(),
+  ]);
+
+  await pipeline.run(test);
+}
+
+const dillId = const DataId("dill");
+const jsId = const DataId("js");
+
+// Step that compiles sources in a module to a .dill file.
+class SourceToDillStep implements IOModularStep {
+  @override
+  DataId get resultId => dillId;
+
+  @override
+  bool get needsSources => true;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [];
+
+  @override
+  bool get onlyOnMain => false;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: source-to-dill on $module");
+    // We use non file-URI schemes for representeing source locations in a
+    // root-agnostic way. This allows us to refer to file across modules and
+    // across steps without exposing the underlying temporary folders that are
+    // created by the framework. In build systems like bazel this is especially
+    // important because each step may be run on a different machine.
+    //
+    // Files in packages are defined in terms of `package:` URIs, while
+    // non-package URIs are defined using the `dart-dev-app` scheme.
+    String rootScheme = 'dev-dart-app';
+    String sourceToImportUri(Uri relativeUri) {
+      if (module.isPackage) {
+        var basePath = module.packageBase.path;
+        var packageRelativePath = basePath == "./"
+            ? relativeUri.path
+            : relativeUri.path.substring(basePath.length);
+        return 'package:${module.name}/$packageRelativePath';
+      } else {
+        return '$rootScheme:/$relativeUri';
+      }
+    }
+
+    // We create a .packages file which defines the location of this module if
+    // it is a package.  The CFE requires that if a `package:` URI of a
+    // dependency is used in an import, then we need that package entry in the
+    // .packages file. However, after it checks that the definition exists, the
+    // CFE will not actually use the resolved URI if a library for the import
+    // URI is already found in one of the provided .dill files of the
+    // dependencies. For that reason, and to ensure that a step only has access
+    // to the files provided in a module, we generate a .packages with invalid
+    // folders for other packages.
+    // TODO(sigmund): follow up with the CFE to see if we can remove the need
+    // for the .packages entry altogether if they won't need to read the
+    // sources.
+    var packagesContents = new StringBuffer();
+    if (module.isPackage) {
+      packagesContents.write('${module.name}:${module.packageBase}\n');
+    }
+    Set<Module> transitiveDependencies = _computeTransitiveDependencies(module);
+    for (Module dependency in transitiveDependencies) {
+      if (dependency.isPackage) {
+        packagesContents.write('${dependency.name}:unused\n');
+      }
+    }
+
+    await File.fromUri(root.resolve('.packages'))
+        .writeAsString('$packagesContents');
+
+    var sdkRoot = Platform.script.resolve("../../../../");
+    var platform =
+        computePlatformBinariesLocation().resolve("dart2js_platform.dill");
+
+    List<String> workerArgs = [
+      sdkRoot.resolve("utils/bazel/kernel_worker.dart").toFilePath(),
+      '--no-summary-only',
+      '--target',
+      'dart2js',
+      '--multi-root',
+      '$root',
+      '--multi-root-scheme',
+      rootScheme,
+      '--dart-sdk-summary',
+      '${platform}',
+      '--output',
+      '${toUri(module, dillId)}',
+      '--packages-file',
+      '$rootScheme:/.packages',
+      ...(transitiveDependencies
+          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+      ...(module.sources.expand((uri) => ['--source', sourceToImportUri(uri)])),
+    ];
+
+    var result = await _runProcess(
+        Platform.resolvedExecutable, workerArgs, root.toFilePath());
+    _checkExitCode(result, this, module);
+  }
+}
+
+// Step that invokes dart2js on the main module by providing the .dill files of
+// all transitive modules as inputs.
+class CompileFromDillStep implements IOModularStep {
+  @override
+  DataId get resultId => jsId;
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [dillId];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [dillId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: dart2js on $module");
+    Set<Module> transitiveDependencies = _computeTransitiveDependencies(module);
+    Iterable<String> dillDependencies =
+        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
+    var sdkRoot = Platform.script.resolve("../../../../");
+    List<String> args = [
+      '--packages=${sdkRoot.toFilePath()}/.packages',
+      'package:compiler/src/dart2js.dart',
+      '${toUri(module, dillId)}',
+      '--dill-dependencies=${dillDependencies.join(',')}',
+      '--out=${toUri(module, resultId)}',
+    ];
+    var result =
+        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+  }
+}
+
+/// Step that runs the output of dart2js in d8 and saves the output.
+class RunD8 implements IOModularStep {
+  @override
+  DataId get resultId => const DataId("txt");
+
+  @override
+  bool get needsSources => false;
+
+  @override
+  List<DataId> get dependencyDataNeeded => const [];
+
+  @override
+  List<DataId> get moduleDataNeeded => const [jsId];
+
+  @override
+  bool get onlyOnMain => true;
+
+  @override
+  Future<void> execute(
+      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
+    if (_options.verbose) print("step: d8 on $module");
+    var sdkRoot = Platform.script.resolve("../../../../");
+    List<String> d8Args = [
+      sdkRoot
+          .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
+          .toFilePath(),
+      root.resolveUri(toUri(module, jsId)).toFilePath(),
+    ];
+    var result = await _runProcess(
+        sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());
+
+    _checkExitCode(result, this, module);
+
+    await File.fromUri(root.resolveUri(toUri(module, resultId)))
+        .writeAsString(result.stdout);
+  }
+}
+
+/// Helper to compute trnsitive dependencies from [module].
+Set<Module> _computeTransitiveDependencies(Module module) {
+  Set<Module> deps = {};
+  helper(Module m) {
+    if (deps.add(m)) m.dependencies.forEach(helper);
+  }
+
+  module.dependencies.forEach(helper);
+  return deps;
+}
+
+void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
+  if (result.exitCode != 0 || _options.verbose) {
+    stdout.write(result.stdout);
+    stderr.write(result.stderr);
+  }
+  if (result.exitCode != 0) {
+    exitCode = result.exitCode;
+    Expect.fail("${step.runtimeType} failed on $module");
+  }
+}
+
+Future<ProcessResult> _runProcess(
+    String command, List<String> arguments, String workingDirectory) {
+  if (_options.verbose) {
+    print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
+  }
+  return Process.run(command, arguments, workingDirectory: workingDirectory);
+}
+
+String get _d8executable {
+  if (Platform.isWindows) {
+    return 'third_party/d8/windows/d8.exe';
+  } else if (Platform.isLinux) {
+    return 'third_party/d8/linux/d8';
+  } else if (Platform.isMacOS) {
+    return 'third_party/d8/macos/d8';
+  }
+  throw new UnsupportedError('Unsupported platform.');
+}
+
+class _Options {
+  bool showSkipped = false;
+  bool verbose = false;
+  String filter = null;
+
+  static _Options parse(List<String> args) {
+    var parser = new ArgParser()
+      ..addFlag('verbose',
+          abbr: 'v',
+          defaultsTo: false,
+          help: "print detailed information about the test and modular steps")
+      ..addFlag('show-skipped',
+          defaultsTo: false,
+          help: "print the name of the tests skipped by the filtering option")
+      ..addOption('filter',
+          help: "only run tests containing this filter as a substring");
+    ArgResults argResults = parser.parse(args);
+    return _Options()
+      ..showSkipped = argResults['show-skipped']
+      ..verbose = argResults['verbose']
+      ..filter = argResults['filter'];
+  }
+}
