File Types and Bundling
What ships in a build, in what order it runs, and whether you need an index file.
This page answers the practical build questions: which files end up in your deploy, what order they execute in, and what an index file does (and doesn't) control. For the detection algorithm itself, see Entry Point Detection. For output formats and embeds, see Deployment Modes.
What Gets Included
Every buildable file in your project ships — you don't need an index file to include anything.
In bundled mode (the default), Odyn scans your project's import graph and finds the entry points: files that no other file imports. It then generates an internal entry that pulls in every entry point, and each entry point pulls in whatever it imports. The result: files that are imported ship because something imports them, and files that nothing imports ship because they become entry points themselves. Either way, they're in the bundle.
Tree-shaking is disabled in bundled mode, so nothing is silently dropped —
if a file is in your project and it's a buildable type, its code is in
bundle.js. The only ways a JS file stays out of the output:
- It's a barrel file (re-exports only, no executable code) — its re-exported code ships via the files it points to.
- It's empty.
- It's excluded from the build via its file settings.
Non-buildable types (.txt, .md, .json, .html, .svg) are stored with
your project but never included in builds. See
Supported File Types.
Execution Order
Inclusion and order are separate questions. Everything ships either way — but what runs first depends on how your files reference each other:
- Files connected by imports run in dependency order: when file A imports file B, B executes before A's own code. This is standard ES module behavior, and it's guaranteed regardless of anything else.
- Files nothing imports (independent entry points) run in explorer order — the top-to-bottom order of your file tree, including folders. Drag files or folders in the tree to change it.
So a project of standalone side-effect files (a core/ folder with GSAP
setup, a components/ folder with widgets) runs top-to-bottom through the
file tree. Keep setup files above the files that depend on them — if
components/slider.js needs a plugin registered by core/gsap-setup.js,
core/ must sit above components/ in the tree.
If you want ordering that survives any tree rearrangement, make it explicit with an index file (see below) or have dependent files import what they need.
Do You Need an Index File?
No — not for inclusion. An index.js that side-effect-imports your other
files was never what got them deployed; they ship with or without it.
What an index file does buy you:
- Explicit execution order. Your imports run top-to-bottom as written, immune to file-tree rearrangement. Files the index doesn't import still ship (they become entry points), so a partial index gives you explicit ordering for the imported subset and explorer ordering for the rest.
- A single entry in per-file mode. In
per-file mode,
entry points map to output files and embed tags. With an index, you get one
module (plus shared chunks). Without one, every file becomes its own
<script type="module">tag.
If you're in bundled mode and happy managing order via the file tree, deleting the index is a perfectly valid setup.
Module and Non-Module Files
Both kinds of JS files are included in bundled mode; they're just handled differently under the hood:
- Module files (anything using
import/export) are imported, so standard module semantics apply — each executes exactly once, even if multiple files import it. - Plain script files (no
import/export) are inlined as-is to preserve their side effects and top-level behavior.
One restriction follows from the bundled output being a single classic
script: top-level await is not supported in bundled mode. Wrap it in
an async function and call it (async function init() { await ...; } init();), or use per-file mode where module scripts allow it.
What's Never Bundled: External Libraries
Bare imports of npm packages — import gsap from "gsap" — are not
bundled. Odyn resolves imports between your project files only. External
libraries must load as their own <script> tags before your bundle (add
them via the Dependencies panel, which puts them in your embed code
automatically). The build warns you when it finds a bare import so you can
confirm the library is loaded externally.
Quick Reference
| Question | Bundled (default) | Per-file | Folder bundle |
|---|---|---|---|
| File nothing imports | Ships (becomes an entry point) | Ships as its own module + script tag | Ships within its folder's bundle |
| File imported by another | Ships via the importer | Ships inside the importer's output/chunks | Ships via the importer |
| Execution order | Import order where imported; explorer order between independent files | Browser loads each module tag; imports resolve per module | Explorer order within the folder |
| Index file needed? | No (optional, for explicit order) | No (optional, for a single entry) | No |
| Tree-shaking | Off — everything ships | On | Off |