Skip to main content

Declarative, typed,pattern matchingfor React

No more if/else/switch

react-matchez is a first-class-React, generic, strongly-typed, solution that you can use to build your own domain-specific matching solutions—and reduce drastically the if/else/switch boilerplate from your components.

Easy-to-reason-about, familiar, API

Matching patterns isn't a new idea in the React world. We have plenty of domain-specific matching/branching solutions, like react-router (declarative matching for routes) and react-device-detect (declarative matching for device type).

Besides the key core Match, With, and When components, react-matchez also provides you with extra helpers like Switch and Exact, inspired by react-router.

export type Data =
  | { type: "text"; content?: string }
  | { type: "img"; extension?: string };
  
export default function MyComponent() {
  const response = useApiRequest();

  const { Switch, Exact, With, Otherwise } = usePatternMatch<Data>();

  return (
    {/* Renders ONLY the first match */}
    <Switch value={response}>
      {/* Matches ANY image */}
      <With type="img">Image</With>
      {/* Compiler fails ("extension" not provided) */}
      <Exact type="img">Image</Exact>
      {/* Matches ONLY .jpg images */}
      <Exact type="img" extension="jpg">
          Image
      </Exact>
      {/* Matches ONLY .png images */}
      <Exact type="img" extension="png">
          Image
      </Exact>
      <Otherwise>Default</Otherwise>
    </Switch>
  );
}

Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Match + React.Suspense + React.lazy() = 💖

react-matchez plays really well with Suspense/lazy in scenarios of feature/browser/OS detection.

Combine the three of them and you'll have your users downloading only the actual component bundle that matches your condition.

const supportsSensor = () => Boolean(window.AmbientLightSensor);

const AmbientLight = React.lazy(() => import("./AmbientLight"));

const Fallback = React.lazy(() => import("./Fallback"));

export default function MyComponent() {
  const { Match, When, Otherwise } = usePatternMatch();

  return (
    <Suspense fallback={"Loading"}>
      <Match>
        <When predicate={supportsSensor}>
          <AmbientLight />
        </When>
        <Otherwise>
          <Fallback />
        </Otherwise>
      </Match>
    </Suspense>
  );
}

Full set of features

Everything you need to bring declarative code branching to your apps.

Works on any data structure

Nested objects, arrays, tuples, Sets, Maps and all primitive types.

Expressive, typesafe, API

Helpful type inference + support for predicates and not patterns for more complex scenarios.

Exact matching support

Enforces that you are matching every possible part of your shape.

~7.4 kB

A small bundle footprint that doesn't impact a lot your final bundle size.

Write better and safer code

Pattern matching lets you express complex conditions in a single, compact expression. Your code becomes shorter and more readable. Compiler-backed exactness checking ensures you thought of every possible property.