Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
AI & KI NachrichtenIs the AI industry really ready to slow down?(20.09.2026 um 20:56 Uhr)
Sichere ProgrammierungThe audio bugs nobody warns you about when you build a mobile looper(20.09.2026 um 20:18 Uhr)
Sichere ProgrammierungA Successful Response Can Still Belong to the Wrong Screen(20.09.2026 um 20:23 Uhr)
Sichere ProgrammierungGzip 1.15 fixes a wrong-file deletion race(20.09.2026 um 20:32 Uhr)
Sichere ProgrammierungWhen SQL Has Nothing to Say: Handling NULLs(20.09.2026 um 20:35 Uhr)
Sichere ProgrammierungWeb Programming in C++ with WFC(20.09.2026 um 20:37 Uhr)
AI & KI NachrichtenIs the AI industry really ready to slow down?(20.09.2026 um 20:56 Uhr)
Sichere ProgrammierungThe audio bugs nobody warns you about when you build a mobile looper(20.09.2026 um 20:18 Uhr)
Sichere ProgrammierungA Successful Response Can Still Belong to the Wrong Screen(20.09.2026 um 20:23 Uhr)
Sichere ProgrammierungGzip 1.15 fixes a wrong-file deletion race(20.09.2026 um 20:32 Uhr)
Sichere ProgrammierungWhen SQL Has Nothing to Say: Handling NULLs(20.09.2026 um 20:35 Uhr)
Sichere ProgrammierungWeb Programming in C++ with WFC(20.09.2026 um 20:37 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Static Imports Are Undermining JavaScript’s Isomorphism

Reagiere als Erste:r — dein Feedback zählt!

TL;DR

  • Static imports bind dependencies at module-load time.
  • Early binding encodes platform assumptions.
  • Declared dependencies move those decisions to the composition root.
  • This is not a new module system. It is standard Dependency Injection applied at the module level.

JavaScript runs natively in both the browser and on the server. That makes true isomorphism possible.

And yet modern JavaScript architecture quietly works against it.

Consider:

import fs from "node:fs";

This line embeds a Node-only capability directly into the module. A browser cannot satisfy "node:fs" by default. The module is no longer isomorphic.

The issue is not fs.
The issue is early binding.

Static imports resolve dependencies during module evaluation. The host fixes the graph before your code runs. If a dependency is platform-specific, the module becomes platform-specific.

Making dependencies explicit

Instead of binding immediately, a module can declare what it needs.

// user-service.mjs

export const __deps__ = {
  fs: "node:fs",
  logger: "./logger.mjs",
};

export default function makeUserService({ fs, logger }) {
  return {
    readUserJson(path) {
      const raw = fs.readFileSync(path, "utf8");
      logger.log(`Read ${raw.length} bytes`);
      return JSON.parse(raw);
    },
  };
}

The module imports nothing directly.
It declares a dependency contract and receives concrete implementations from the outside.

This is Dependency Injection applied at the module level. The composition root decides what gets passed in.

Manual composition root

Node

// node-entry.mjs

import fs from "node:fs";
import logger from "./logger.mjs";
import makeUserService from "./user-service.mjs";

const service = makeUserService({ fs, logger });

Browser

// browser-entry.mjs

import fsAdapter from "./browser-fs-adapter.mjs";
import logger from "./logger.mjs";
import makeUserService from "./user-service.mjs";

const service = makeUserService({
  fs: fsAdapter,
  logger,
});

The module did not change.
Only the composition root changed.

Platform decisions stay at the edge of the system — and because dependencies are injected explicitly, tests can pass fakes directly instead of mocking module imports.

Automating composition

Because the contract is exposed via __deps__, the composition root can be made data-driven:

// link.mjs

export async function link(entrySpecifier, overrides = {}) {
  const mod = await import(entrySpecifier);
  const depsSpec = mod.__deps__ ?? {};
  const deps = {};

  for (const [name, specifier] of Object.entries(depsSpec)) {
    const finalSpecifier = overrides[specifier] ?? specifier;
    const imported = await import(finalSpecifier);
    deps[name] = imported.default ?? imported;
  }

  return mod.default(deps);
}

Node

const service = await link("./user-service.mjs");

Browser

const service = await link("./user-service.mjs", {
  "node:fs": "./browser-fs-adapter.mjs",
});

Binding becomes explicit program logic, not loader side effects.

How this differs from import maps and exports

  • Import maps control specifier resolution at load time (host-level).
  • package.json exports select entry points per environment (package-level).
  • Bundlers optimize graphs at build time.
  • Composition root + DI decides which concrete capabilities a module receives at runtime (application-level).

Import maps answer: Where is this module?
Composition root answers: Which capability does this module receive?

Different layers, different concerns.

Trade-offs

This approach is not free:

  • You lose some static analyzability and tree-shaking precision.
  • TypeScript integration becomes more manual.
  • It’s unnecessary for small or purely single-runtime apps.
  • It introduces architectural discipline (composition root).

This is a tool, not a default.

When to use it

Use it when:

  • You want true cross-runtime modules (Node + browser + edge).
  • You want environment decisions centralized.
  • You care about testability without heavy mocking.
  • You want explicit capability boundaries.

Do not use it when:

  • Your app is single-runtime.
  • Build-time optimization and tree-shaking are primary concerns.
  • Simplicity outweighs architectural flexibility.

Static imports are not wrong. They are efficient and idiomatic.

But they bind early.
And early binding encodes platform assumptions.

If we care about preserving JavaScript’s isomorphism, we should be deliberate about where binding happens.

Because once a module binds to a platform capability during evaluation, it has already chosen its platform.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Static Imports Are Undermining JavaScript’s Isomorphism

Thematisch verwandte Begriffe: Static, Imports, Undermining, JavaScripts · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-93956 | A flaw has been found in olivier-ls PHP-FTS up to 1.1.2. Affected by thi…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick