Enums

The Bundle Size Explosion

It was performance review time. Our web app was loading slowly on mobile. I opened the Chrome DevTools Network tab and saw our main JavaScript bundle: 487KB. For a relatively simple app.

I ran webpack-bundle-analyzer and found the culprit:

// constants.ts - Our old enum-heavy code
enum UserRole {
  Admin = 'ADMIN',
  Moderator = 'MODERATOR',
  User = 'USER',
  Guest = 'GUEST'
}

enum ProductCategory {
  Electronics = 'ELECTRONICS',
  Clothing = 'CLOTHING',
  Books = 'BOOKS',
  Home = 'HOME',
  Sports = 'SPORTS'
  // ... 47 more categories
}

enum EventType {
  Click = 'CLICK',
  Hover = 'HOVER',
  Scroll = 'SCROLL',
  // ... 23 more event types
}

// ... 15 more large enums

TypeScript compiled these to:

Each enum generated an IIFE (Immediately Invoked Function Expression). With 18 enums averaging 20 values each, we had 40KB of enum boilerplate in the bundle.

I refactored to const enums and union types:

Result: Bundle size dropped to 447KB (40KB saved). Page load improved by 0.8 seconds on 3G.

This article covers when to use enums, when to avoid them, and the patterns that keep your bundle lean.


Numeric Enums

Default enum type with auto-incrementing numbers.

Basic Numeric Enum

Custom Starting Value

Mixed Auto-Increment


String Enums

Enums with string values.

Basic String Enum

Why String Enums?


Const Enums

Compile-time-only enums that don't generate runtime code.

Regular Enum (Runtime Code)

Const Enum (No Runtime Code)

Real-World Example

Bundle size benefit: If you use an enum 100 times, regular enum = IIFE + 100 references. Const enum = 100 inlined strings.


Enum Member Types

Each enum member is its own type.

Literal Type Narrowing


Computed and Constant Members

Constant Members


Reverse Mappings

Numeric enums have automatic reverse mappings.

Numeric Enum Reverse Mapping

String Enums Don't Have Reverse Mappings


Enums at Runtime

Understanding how enums compile helps you choose the right approach.

Regular Enum Compiled Output

Const Enum Compiled Output


When to Use Enums

Good Use Cases

1. Fixed Set of Related Constants

2. State Machines

3. Bit Flags


When NOT to Use Enums

Use Union Types Instead

Bad - Enum Overkill:

Good - Union Type:

Use Constants for Single Values

Bad - Enum for API Constants:

Good - Separate Constants:


Enum Alternatives

Union Types

as const Objects

Branded Types


Real-World Patterns

1. HTTP Status Codes

2. Feature Flags

3. Event Types


Common Mistakes I Made

1. Using Enums for Configuration

Bad:

Good:

2. Not Using Const Enums

Bad (Bloats Bundle):

Good (Inlined):

3. Using Enums When Union Types Suffice

Bad:

Good:


Your Challenge

Build a type-safe state machine for an order system:


Key Takeaways

  1. Numeric enums - auto-incrementing numbers, have reverse mappings

  2. String enums - explicit string values, better debugging

  3. Const enums - compile-time only, no runtime code, smaller bundle

  4. Regular enums - generate runtime code (IIFEs)

  5. Union types - often better than enums for simple cases

  6. as const objects - alternative with runtime iteration

  7. Use const enum when you don't need runtime reflection

  8. Use union types for simple string literals


What I Learned

The bundle size incident taught me: not every constant needs an enum.

Before optimization:

After refactoring:

The decision tree I use now:

  1. Need runtime iteration?as const object

  2. Simple string literals? → Union type

  3. Bit flags or numeric values? → Enum (maybe const)

  4. Complex state machine? → Const enum

  5. Small, frequently used set? → Const enum

Enums aren't bad – they're just often overkill. TypeScript gives us multiple ways to express constants. Use the lightest tool that solves the problem.

A 40KB bundle reduction is 0.8 seconds faster on 3G. Choose wisely.


Next: Modules and Declaration Files

In the next article, we'll explore TypeScript's module system and declaration files. You'll learn how I debugged a 6-hour "module not found" nightmare and the patterns that prevent it.

Last updated