The structure of your app’s directories affects how your app’s code
imports other code,
whether from your own app or from a different package.
Possible app structures
As the following figure shows,
a very simple polymer.dart app might have only a single HTML file
under web, plus a pubspec.yaml file.
By default, each HTML file under web is an entry point—a
page that the user can navigate to.
Apps often have additional files under lib.
Both the web and lib directories can contain HTML, CSS, Dart,
image, and other files.
Generally, the assets (such as images)
that an HTML or Dart files uses
are near that file in the directory structure.
Dart, HTML, and CSS files often import assets,
such as other Dart files, HTML files, CSS files, and images.
The syntax for importing assets depends on the following:
Whether the importing file is a Dart file
Whether the importing file is an entry point
Whether the importing file is under web or under lib
Whether the imported file is under the same top-level directory
(web or lib) or in another package
Within a package, files under web can import files under
either web or lib.
However, files under lib can import only files under lib.
Both web and lib files can import files from
The examples in the following sections use
a package named a that depends on the polymer package
and a package named b.
The a and b packages have
this directory structure:
Into web/ from web/
Within web, both Dart and non-Dart files use relative paths when
importing other files under web.
Within web, both Dart and non-Dart files use package paths
when importing from lib—even
when those files are in the same package.
Dart package paths start with
while non-Dart package paths start with
For package_name use the value of the
name field in pubspec.yaml.
Into a Dart file
The Dart code is always the same,
no matter how deeply under web the Dart file is nested.
Use a simple HTTP server.
You can run the server in the top directory of your app,
and point Dartium to the URL of an entry point.
cd <top directory of app>
python -m SimpleHTTPServer
In Dartium, browse to
The rules behind the import syntax
The import syntax is the result of some rules that polymer.dart defines,
in addition to what pub stipulates:
Every entry point has a packages directory,
which is why its package import paths start with packages/.
Non-entry-point files under web use the packages directory
of the entry point that imports them.
Two entry points in different directories
can’t import the same non-entry-point web file.
(Instead, you can move the non-entry-point file to lib.)
The rules are easier to follow if
you know how pub get places files.
How the directory structure changes
Recall the directory structure from before:
When you run pub get at the top of package a,
a packages directory appears under each directory in web.
Note that no lib directory is under the packages directory.
When you launch web/a1_ep.html in Dartium,
Dartium loads package imports from web/packages/.
When you launch web/a2/a2_ep.html in Dartium,
the package imports come from web/a2/packages/.
However, when web/a3/a3.html imports lib/a5/a5.html,
as a non-entry point a3.html must
walk up to the packages directory that
lives next to its entry point (a1_ep.html)
and then load the file from there:
Because pub generates symlinks to the packages directory under a3,
you might be tempted to write packages/a/a5/a5.html,
but that’s incorrect.
When a5/a5.html (originally under lib)
(also originally under lib, but in the b package),
a5.html must first walk out to be just above
the top-level packages directory.
It’s under packages/a/a5, so it must walk up 3 directories
before it can continue the path with packages:
Using correct import syntax
allows the code in lib to be used by your package,
as well as by code outside your package,
Why the rules exist
The motivation behind polymer.dart’s import rules is that
URLs must work under many scenarios at once:
URLs must work in Dartium without any code transformation:
resolving the path in the context of a simple HTTP server,
or using file:/// URLs, should yield a valid path to assets.
The packages directory is safe to use because
pub already creates it next to the entry points of your application.
URLs must be canonical.
Multiple URLs reaching the same asset must
resolve to the same absolute URL,
whether the URL comes from a Dart file or an HTML file.
If you use the correct import syntax,
then the polymer transformer ensures
that the URLs are canonical.
For example, say you have an import like this:
<link rel="import" href="packages/c/c.html">
Also say that c.html has this:
<script type="application/dart" src="c.dart">
If a Dart file also loads "package:c/c.dart",
then a tool needs to make sure that both versions of c.dart are
loaded from the same URL.
you may see errors at runtime like
“A is not a subtype of A.”
When you use the correct import syntax,
polymer.dart can detect the pattern in
the HTML-import URL that contains packages/
and canonicalize the import
by converting packages/c/c.dart into package:c/c.dart under the hood.
URLs must continue to be valid after applications are built.
Technically a pub transformer could do this automatically.
However, to make sure that code works also in Dartium
with a simple HTTP server,
the polymer transformer doesn’t fix URLs;
it just detects inconsistencies and
produces an error message.