Web frontend

A web application running in the browser: JavaScript, compiled TypeScript, WebAssembly, style sheets, fonts, icons.

What actually happens

Question Answer
Does a third party receive the software in executable form? Yes — the browser downloads and runs the code
Does a third party interact with it over a network? Yes, but that is secondary here
Is the component linked to your code? Yes, statically, in a single file

The point almost everyone misses. A web frontend distributes source code to every visitor. It is not a service: it is a software delivery, to thousands of anonymous recipients, several times a day.

A team saying “you do SaaS, the GPL does not concern you” is right about the backend and wrong about the frontend. Same product, two opposite regimes.

The verdict per family

Family Verdict Reason
Permissive Allowed, but attribution survives bundling badly: see below
Weak copyleft, file (MPL, EPL) Per-file reciprocity, but the bundle dissolves the notion of a file
Weak copyleft, library (LGPL) Dynamic linking does not exist in a bundle: treat as strong copyleft
Strong copyleft (GPL) Distribution is established: the combined work’s source is owed to every visitor
Network copyleft (AGPL) Distribution and network combined
Source-available The code is delivered to the client anyway, which these licences do not anticipate
Non-commercial content (CC-BY-NC) Common on icons and illustrations, and prohibited in a product you sell

Why the bundler makes everything worse

In a native application the combined-work question is arguable: dynamic linking? separate process? stable interface? In a frontend, there is no argument to have.

The bundler takes your code and the dependencies’, tree-shakes, renames symbols, inlines functions, and emits a single file. There is no longer any observable boundary between your code and the third-party component.

Consequences:

  • the “you only link dynamically” argument is unavailable;
  • the “these are separate programs” argument is unavailable;
  • a GPL component in the dependency graph contaminates, in practice, the shipped artefact.

The only architectural remedy is real isolation: loading the component from a separate origin, in its own iframe or worker, with no shared code. It is heavy, and it cannot be decided after the fact.

Attribution, problem number one for permissive licences

Permissive licences require preserving copyright and licence notices. Minification removes them all.

What to put in place:

Measure Effect
Licence banner preservation in the bundler Keeps /*! … */ blocks marked for preservation
Generating a licenses.txt at build time From the SBOM, with the full licence texts
An accessible link from the application Footer, “Legal notices” page, “About”
A blocking CI check Build fails if the attribution file is not generated

Without those four measures, a modern frontend breaches dozens of permissive licences at once. It is the most widespread failing in the field, and the easiest to fix.

Pitfalls specific to frontends

Source maps. Publishing source maps in production exposes your source code, and with it the exact composition of the bundle. That is often how a third party establishes a violation.

Fonts. OFL-1.1 allows redistribution but carries a reserved font name clause: a modified font — glyph subsetting, format conversion, renaming — may not keep its original name. Font subsetting, a routine optimisation, is a modification.

Icons and illustrations. This is where the real problems are. CC-BY-NC prohibits commercial use; CC-BY-SA requires share-alike on the derivative; CC-BY-ND prohibits cropping and recolouring. An icon set picked up without checking is a far more immediate risk than a JavaScript library.

Development dependencies shipped by mistake. A test-only component that ends up in the production bundle enters the distributed scope.

Third-party scripts loaded from a CDN. You do not distribute them — but they introduce an external dependency that raises other questions, of security this time.

WebAssembly. A module compiled from C or Rust carries its native dependencies’ licences, invisible in the JavaScript package graph. The frontend SBOM must cover the WebAssembly build chain.

What the CRA adds

The frontend is part of the product. Its components belong in the SBOM just as much as the backend’s — and they rarely are, in the arrangements one encounters, where the inventory usually stops at server dependencies.

The Annex I requirements apply there too: data minimisation, integrity protection, no known exploitable vulnerabilities. A vulnerable JavaScript dependency served to the browser is a vulnerability of the product.