DEV Community

Cover image for A practical guide to the new import features in Deno — with comparisons, do’s & don’ts, and an illustration prompt.
netsi1964 🙏🏻
netsi1964 🙏🏻

Posted on

A practical guide to the new import features in Deno — with comparisons, do’s & don’ts, and an illustration prompt.

TL;DR

  • Import Attributes are here, using the with keyword to specify the module type.
  • Natively import JSON, text, and even binary files directly into your modules.
  • Use the with { type: "json" } syntax for JSON modules, which is now stable.
  • Leverage the experimental with { type: "text" } and with { type: "bytes" } for raw file imports, which requires the --unstable-raw-imports flag.
  • Seamlessly import from npm using npm: specifiers for greater compatibility with the existing JavaScript ecosystem.

1. What’s new with import?

Deno continues to evolve its module system to be more standards-aligned and powerful. The latest versions introduce "Import Attributes," a standards-track feature that clarifies how non-JavaScript files should be handled. This is done using the with keyword in an import statement.

// Import a JSON configuration file
import config from "./config.json" with { type: "json" };

// Import a startup script as a plain text string (experimental)
import startupScript from "./init.sql" with { type: "text" };

// Import a WebAssembly binary as a module (experimental)
import wasm from "./module.wasm" with { type: "bytes" };
Enter fullscreen mode Exit fullscreen mode

This syntax tells the Deno runtime explicitly what kind of data to expect, making the process more secure and predictable than relying on bundler-specific magic.


2. Where can I use these new import types?

Module Type Supported? What you get Notes
JSON ✅ Stable object Natively parsed JSON data.
Text ✅ Experimental (--unstable-raw-imports) string The raw text content of the file.
Bytes ✅ Experimental (--unstable-raw-imports) Uint8Array The raw binary data of the file.
npm modules ✅ Stable Module exports Use npm:package-name to import from the npm registry.
JSR modules ✅ Stable Module exports Use jsr:@scope/package for versioned, TypeScript-native modules.

🔗 Deno Docs: https://docs.deno.com/runtime/fundamentals/modules/#import-attributes


3. import attributes vs. other loading methods

Purpose Method Output Typical use
Importing structured data import data from "./cfg.json" with { type: "json" } object Loading configuration, manifests, or static data.
Importing raw text import txt from "./file.txt" with { type: "text" } string Loading templates, scripts (SQL, shell), or articles.
Importing binary data import bin from "./file.wasm" with { type: "bytes" } Uint8Array Loading WebAssembly modules, images, or other assets.
Traditional file reading Deno.readTextFile() / Deno.readFile() `Promise<string Uint8Array>`
Importing JS/TS code import { func } from "./mod.ts" Module exports The standard way to import application logic.

4. Do’s ✅ and Don’ts ❌

✅ Do ❌ Don’t
Use with for import attributes; the old assert syntax is deprecated. Forget the --unstable-raw-imports flag for text and bytes imports.
Manage third-party dependencies with jsr: and npm: specifiers. Manually fetch and parse JSON when you can import it directly.
Use import maps in deno.json to create clear, version-locked dependencies. Mix stable and unstable import features without being aware of the implications.
Check for official JSR packages before falling back to npm for better Deno integration. Assume text/bytes imports work in older Deno versions; they are a recent addition.

5. Real-world snippet: Loading configuration and a welcome message

Imagine an application that needs a configuration file and a "message of the day" from a separate text file.

// config.json
{
  "port": 8080,
  "logging": true,
  "features": ["alpha", "beta"]
}

// motd.txt
Welcome to the application! Today's focus is on robust module loading.

// main.ts
import config from "./config.json" with { type: "json" };
import message from "./motd.txt" with { type: "text" };

console.log(`--- Message of the Day ---`);
console.log(message);
console.log(`------------------------`);

if (config.logging) {
  console.log(`Starting server on port: ${config.port}`);
  console.log(`Enabled features: ${config.features.join(', ')}`);
}

// To run this (as of Deno 2.4+):
// deno run --allow-read --unstable-raw-imports main.ts
Enter fullscreen mode Exit fullscreen mode

Key takeaway

Deno's new import features, especially import attributes for JSON, text, and bytes, make your code more explicit and robust. By handling different file types directly within the ES module system, Deno eliminates boilerplate code, enhances security, and improves tooling integration, bringing your non-JavaScript assets into the main module graph.

Top comments (0)