Skip to content

Zero dependencies #510

Open
Open

Description

@kallal79

Why this matters (impact)

  • Developer trust depends on clear and accurate claims — "zero dependencies" is a major selling point.
  • Hidden runtime dependencies alter installation and bundling expectations (some toolchains need @babel/runtime installed explicitly).
  • Marketing and documentation inconsistency can negatively affect adoption.

This script programmatically demonstrates the inconsistency (it checks package.json and scans dist for @babel/runtime):

// (trimmed for brevity here; see file in repo for full script)
// It prints: package dependencies, whether dist files contain "@babel/runtime",
// and the observed website claim vs. actual.

Run: node poc-zero-deps-mismatch.js


Tests (full contents included)

I added/used the following tests :

  1. src/build.no-runtime-deps.test.ts — ensures no @babel/runtime strings in dist JS files
import fs from "fs";
import path from "path";

describe("packaging: runtime dependency consistency", () => {
  it("should not contain @babel/runtime references in dist (claim: Zero dependencies)", () => {
    const distDir = path.resolve(__dirname, "..", "dist");
    const files = fs.readdirSync(distDir).filter((f) => f.endsWith(".js"));
    const offending: string[] = [];
    for (const f of files) {
      const content = fs.readFileSync(path.join(distDir, f), "utf8");
      if (content.indexOf("@babel/runtime") !== -1) offending.push(f);
    }
    expect(offending).toHaveLength(0);
  });
});
  1. src/security.prototype-pollution.test.ts — defensive security test ensuring malicious field names cannot pollute prototypes
import { createForm } from "./index";

describe("security: prototype pollution", () => {
  beforeEach(() => {
    delete (Object.prototype as any).__polluted_by_test;
    delete (Object.prototype as any).polluted;
  });

  it("should not allow prototype pollution via __proto__ path", () => {
    const form = createForm({ onSubmit: () => {} });
    // @ts-ignore - intentional malicious key simulation
    form.change("__proto__.polluted", "yes");

    expect(({} as any).polluted).toBeUndefined();
    expect((Object.prototype as any).polluted).toBeUndefined();
  });

  it("should not allow prototype pollution via constructor.prototype path", () => {
    const form = createForm({ onSubmit: () => {} });
    // @ts-ignore
    form.change("constructor.prototype.__polluted_by_test", "yes");

    expect(({} as any).__polluted_by_test).toBeUndefined();
    expect((Object.prototype as any).__polluted_by_test).toBeUndefined();
  });
});

Build & Test Evidence (what I ran locally)

  • PoC run: node poc-zero-deps-mismatch.js — report printed showing no runtime deps after the inlining fix.
    • Test suites: 26 total
    • Passed: 25
    • Failed: 1 (unrelated test: src/FinalForm.validating.test.ts shows a timing/race expectation mismatch)
    • Tests: 341 passed, 1 failed (total 342)

Fix Options & Recommendation

A) Inline Babel helpers at build time (implemented in branch fix/zero-deps-mismatch):

  • Change Babel helper behavior to babelHelpers: 'bundled' in rollup.config.mjs and remove @babel/plugin-transform-runtime.
  • Remove @babel/runtime from runtime dependencies in package.json.
  • Pros: Restores true "Zero dependencies" for consumers, keeps website claim valid.
  • Cons: Slight increase in minified bundle size (roughly +2KB minified; gzipped similar), but overall still small.

B) Update website/README to clarify/remove the "Zero dependencies" claim:

  • Simpler and non-invasive: change documentation and website copy to reflect reality.
  • Cons: Undermines original promise and may disappoint users who chose the package specifically for zero deps.

Files added/changed while investigating (local branch: fix/zero-deps-mismatch)

  • Modified: rollup.config.mjs (changed babelHelpers from runtime to bundled, removed @babel/plugin-transform-runtime entry).
  • Modified: package.json (removed @babel/runtime from dependencies).
  • Added: src/build.no-runtime-deps.test.ts (regression test to catch future regressions).
  • Added: src/security.prototype-pollution.test.ts (security test for prototype pollution attack vectors).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions