JavaScript Proxies: The Hidden Superpower You’re Not Using

Intercept, transform, and observe objects at a fundamental level — without touching the source.

If you’ve ever wanted to validate object properties automatically, track changes reactively, or build a mock API client that feels real — the Proxy object is your tool. Yet somehow it flies under the radar for most developers.

Introduced in ES2015, Proxy wraps an object and lets you intercept fundamental operations — property reads, writes, deletions, and more — via “traps” defined on a handler object.

The anatomy of a Proxy

A Proxy takes two arguments: the target (the object being wrapped) and the handler (an object defining which operations to intercept). Every interceptable operation has a corresponding trap method on the handler.

proxy-basics.js
const handler = {
  get(target, key) {
    return key in target
      ? target[key]
      : `Property "${key}" doesn’t exist`
  },
  set(target, key, value) {
    if (typeof value !== 'number') {
      throw new TypeError('Only numbers allowed')
    }
    target[key] = value
    return true
  }
}

const proxy = new Proxy({}, handler)
proxy.score = 42        // ✓ works
proxy.score = 'oops'   // ✗ TypeError

The get trap runs on every property access. The set trap intercepts every assignment. Return true from set to signal success — otherwise you’ll get a TypeError in strict mode.

Real-world use cases

The real power isn’t abstract. Proxy unlocks patterns that are otherwise painful or impossible.

“A Proxy doesn’t change what your object is — it changes what your object does when the runtime touches it.”

Reactive state

Vue 3’s reactivity system is built entirely on Proxy. When you access a reactive property, Vue’s get trap tracks the dependency. When you mutate it, the set trap schedules re-renders. No syntax overhead. Just assignment.

Input validation

Instead of scattering guard clauses through your codebase, centralise validation in a Proxy handler. The contract lives in one place. Every consumer benefits automatically.

API mocking

Wrap a plain object in a Proxy that intercepts property access and returns async functions. You get a fully-typed mock client that mirrors your real API surface — without any code generation.

Performance considerations

Proxies are not free. Every trap fires a function call. In tight loops over large collections, this adds up. Benchmark before you commit. For most use cases — form state, reactive stores, config validation — the overhead is completely negligible.

The V8 team has steadily optimised Proxy performance since ES2015. Don’t avoid Proxy out of dated fear — measure it first.

?

Andy Pixel

Frontend engineer obsessed with the web platform. Writing about JavaScript, CSS, and creative code. Building things at the edge of what browsers can do.

Stay in the loop

More like this, in your inbox.

Deep-dives on JavaScript, the web platform, and frontend engineering — whenever I publish. No noise.