BitlystBitlyst
PostsSeriesTopicsAbout

Bitlyst

Short, diagram-first posts on JavaScript, React & Next.js. Follow via RSS or the newsletter.

ยฉ 2026 Mohsen Fallahnejad

PostsSeriesTopicsLinksAboutRSSGitHubX
Posts/typescript
Intermediate3 min read

Are TypeScript Enums a Good Idea? (Bundle Size & Runtime)

A practical guide to TypeScript enums, their runtime cost, and better alternatives for modern frontend apps.

Mohsen Fallahnejad

Mohsen Fallahnejad

Dec 30, 2025Discuss

Are TypeScript Enums a Good Idea?

Short answer: usually no, especially in frontend apps where bundle size and runtime behavior matter.

TypeScript enums look convenient, but they come with hidden runtime costs. In most cases, there are better zero-cost alternatives.


๐Ÿง  What Actually Happens with enum#

Numeric enum#

ts
enum Status {
  Idle,
  Loading,
  Success,
}

Generated JavaScript:

js
var Status;
(function (Status) {
  Status[Status["Idle"] = 0] = "Idle";
  Status[Status["Loading"] = 1] = "Loading";
  Status[Status["Success"] = 2] = "Success";
})(Status || (Status = {}));

๐Ÿ‘‰ This means:

  • A real object exists at runtime
  • Extra bytes in your JS bundle
  • Worse tree-shaking than you expect

String enum#

ts
enum Mode {
  Light = "light",
  Dark = "dark",
}

Still generates a runtime object:

js
var Mode = {
  Light: "light",
  Dark: "dark",
};

Better than numeric enums, but still not free.


โš ๏ธ Why Enums Can Be a Problem#

  • โŒ Increase bundle size
  • โŒ Add runtime objects
  • โŒ Harder to tree-shake
  • โŒ Easy to misuse for simple unions

Enums are not erased by TypeScript.


โšก What About const enum?#

ts
const enum Status {
  Idle,
  Loading,
}
  • โœ… Inlined at compile time
  • โœ… Zero runtime cost
  • โŒ Often incompatible with Babel / SWC / isolatedModules
  • โŒ Risky in monorepos or mixed build setups

โš ๏ธ Use only if you fully control your toolchain.


โœ… Better Alternatives (Recommended)#

1๏ธโƒฃ String Literal Unions (Best Default)#

ts
type Mode = "light" | "dark";
  • โœ… Zero runtime cost
  • โœ… Perfect for props, state, API types
  • โŒ No runtime list (by default)

Pair with a list if needed:

ts
export const MODES = ["light", "dark"] as const;
export type Mode = (typeof MODES)[number];

2๏ธโƒฃ as const Object Pattern (Enum-like DX)#

ts
export const Mode = {
  Light: "light",
  Dark: "dark",
} as const;

export type Mode = typeof Mode[keyof typeof Mode];
  • โœ… Small runtime footprint
  • โœ… Tree-shakable
  • โœ… Nice DX: Mode.Dark
  • โœ… Works well with runtime validation

3๏ธโƒฃ Schema-first (APIs, forms)#

ts
const ROLES = ["admin", "user"] as const;
type Role = (typeof ROLES)[number];

Great when used with Zod / Valibot for runtime validation.


๐Ÿง  When Enums Are Actually OK#

Use real enum if:

  • You need runtime iteration
  • You rely on reverse mapping
  • You integrate with legacy code
  • Bundle size is not critical

Enums are not evil โ€” just often overused.


๐Ÿ“Š Comparison Table#

PatternRuntime costTree-shakingDXRecommended
enumโŒโŒโœ…โš ๏ธ
const enumโœ…โœ…โš ๏ธโš ๏ธ
union typeโœ…โœ…โœ…โญ
as const objectโœ…โœ…โœ…โญโญ

โœ… Final Recommendation#

Prefer unions and as const objects in frontend TypeScript.
Reach for enum only when you truly need runtime behavior.

This approach gives you:

  • Smaller bundles
  • Faster startup
  • Clearer intent
  • Fewer build surprises
Filed under#typescript#enums#bundle-size#performance#frontend

Was this worth your time?

One tap tells me what to write more of.

Mohsen Fallahnejad

Written by

Mohsen Fallahnejad

Frontend engineer explaining JavaScript, React & Next.js internals in posts you can finish over coffee. More about me

X โ†—GitHub โ†—LinkedIn โ†—
โ† OlderWeb Workers Explained for Frontend DevelopersNewer โ†’Promise APIs Compared: all vs race vs any vs allSettled

Start the discussion

Questions, corrections, a better approach? I read and reply to every comment.

Read next

Debounce vs Throttle โ€” One Sentence to Remember Forever

Two patterns for taming fast events: debounce waits for silence, throttle limits how often. With examples, code, and interview answers.

Jul 8, 20264 min read1

React memo vs useMemo vs useCallback โ€” When to Use Which

Three React APIs that all say 'memoize' โ€” but they do different things. Clear explanations, examples, and a cheatsheet.

Jun 28, 20263 min read

CDN Explained: What It Is, How It Works, and How to Use It in Next.js

A CDN speeds up your app by serving assets from servers close to your users. Here's how it works and how Next.js takes advantage of it.

Jun 20, 20263 min read2

Get new posts in your inbox

No spam. Unsubscribe any time.

3 min left
Discuss๐Ÿ‘ React
๐Ÿ‘