
Company News
Socket Named Top Sales Organization by RepVue
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.
@oliverlooney/react-brackets
Advanced tools
Dynamic bracket component, usable for brackets such as single elimination and double elimination
Originally created by mohux. This fork is maintained and published as @oliverlooney/react-brackets.

via npm
npm i @oliverlooney/react-brackets
via yarn
yarn add --save @oliverlooney/react-brackets
The simplest usage of this component is
import { Bracket, IRoundProps } from 'react-brackets';
const rounds: IRoundProps[] = [
{
title: 'Round one',
seeds: [
{
id: 1,
date: new Date().toDateString(),
teams: [{ name: 'Team A' }, { name: 'Team B' }],
},
{
id: 2,
date: new Date().toDateString(),
teams: [{ name: 'Team C' }, { name: 'Team D' }],
},
],
},
{
title: 'Round one',
seeds: [
{
id: 3,
date: new Date().toDateString(),
teams: [{ name: 'Team A' }, { name: 'Team C' }],
},
],
},
];
const Component = () => {
return <Bracket rounds={rounds} />;
};
The core shape is similar to the above, since we can customize seeds and titles, you can pass any additional data to a seed or treat the title as a component.
modifying a title of the round is so simple,
import { Bracket, IRoundProps } from 'react-brackets';
import React from 'react';
const Component = () => {
//....
return (
<Bracket
rounds={rounds}
roundTitleComponent={(title: React.ReactNode, roundIndex: number) => {
return <div style={{ textAlign: 'center', color: 'red' }}>{title}</div>;
}}
/>
);
};
Customizing a seed on the other hand is a little bit more complicated, yet still easy, because we need to let the bracket tree to have a consistent design
Any additional data you pass inside a seed object is accessible via renderSeedComponent
import { Bracket, IRoundProps, Seed, SeedItem, SeedTeam, IRenderSeedProps } from 'react-brackets';
import React from 'react';
const CustomSeed = ({seed, breakpoint, roundIndex, seedIndex}: IRenderSeedProps) => {
// breakpoint passed to Bracket component
// to check if mobile view is triggered or not
// mobileBreakpoint is required to be passed down to a seed
return (
<Seed mobileBreakpoint={breakpoint} style={{ fontSize: 12 }}>
<SeedItem>
<div>
<SeedTeam style={{ color: 'red' }}>{seed.teams[0]?.name || 'NO TEAM '}</SeedTeam>
<SeedTeam>{seed.teams[1]?.name || 'NO TEAM '}</SeedTeam>
</div>
</SeedItem>
</Seed>
);
};
const Component = () => {
//....
return <Bracket rounds={rounds} renderSeedComponent={CustomSeed} />;
};
How about if I want to use this component for double elimination losing bracket? the current Seed component only works on single elimination, the answer is fairly simple as well.
import { Bracket, IRoundProps, Seed, SingleLineSeed, SeedItem, SeedTeam, IRenderSeedProps } from 'react-brackets';
import React from 'react';
const CustomSeed = ({seed, breakpoint, roundIndex, seedIndex}: IRenderSeedProps) => {
// ------ assuming rounds is the losers brackets rounds ------
// losers rounds usually got some identical seeds amount like (2 - 2 - 1 - 1)
const isLineConnector = rounds[roundIndex].seeds.length === rounds[roundIndex + 1]?.seeds.length;
const Wrapper = isLineConnector ? SingleLineSeed : Seed;
// mobileBreakpoint is required to be passed down to a seed
return (
<Wrapper mobileBreakpoint={breakpoint} style={{ fontSize: 12 }}>
<SeedItem>
<div>
<SeedTeam style={{ color: 'red' }}>{seed.teams[0]?.name || 'NO TEAM '}</SeedTeam>
<SeedTeam>{seed.teams[1]?.name || 'NO TEAM '}</SeedTeam>
</div>
</SeedItem>
</Wrapper>
);
};
const Component = () => {
//....
return <Bracket rounds={rounds} renderSeedComponent={CustomSeed} />;
};
How to render Single Elimination as a two-sided bracket? You must set twoSided to true, and structure your custom seed render component like below, if you have a custom seed render component.
import { Bracket, RoundProps, Seed, SeedItem, SeedTeam, RenderSeedProps } from 'react-brackets';
import React from 'react';
const CustomSeed = ({seed, breakpoint, roundIndex, seedIndex, isMiddleOfTwoSided}: RenderSeedProps) => {
// breakpoint passed to Bracket component
// to check if mobile view is triggered or not
// mobileBreakpoint is required to be passed down to a seed
const Wrapper = isMiddleOfTwoSided ? SingleLineSeed : Seed
return (
<Wrapper mobileBreakpoint={breakpoint} style={{ fontSize: 12 }}>
<SeedItem>
<div>
<SeedTeam style={{ color: 'red' }}>{seed.teams[0]?.name || 'NO TEAM '}</SeedTeam>
<SeedTeam>{seed.teams[1]?.name || 'NO TEAM '}</SeedTeam>
</div>
</SeedItem>
</Wrapper>
);
};
const Component = () => {
//....
return <Bracket rounds={rounds} renderSeedComponent={CustomSeed} twoSided={true} />;
};
import { Bracket, IRenderSeedProps, Seed, SeedItem, SeedTeam, SeedTime } from 'react-brackets';
const CustomSeed = ({ seed, breakpoint }: IRenderSeedProps) => {
return (
<Seed mobileBreakpoint={breakpoint} className='test'>
<SeedItem className='skeleton-item'>
<div>
<SeedTeam>.</SeedTeam>
<SeedTeam>.</SeedTeam>
</div>
</SeedItem>
<SeedTime mobileBreakpoint={breakpoint} style={{ fontSize: 9 }}>
{seed.date}
</SeedTime>
</Seed>
);
};
const Component = () => {
//....
return <Bracket rounds={rounds} renderSeedComponent={CustomSeed} />;
};
| Prop | Type | Description |
|---|---|---|
| rounds | IRoundProps[] | Array of rounds, each round has {title,array of seeds}, if you're not using a custom seed render, each seed needs an array of teams, each team should have a name |
| mobileBreakpoint | number | This bracket supports responsive design, on window reaching this size, it will trigger mobile swipable view, if you want to disable it, you can pass 0, (default is 992) |
| rtl | boolean | Direction of the bracket as RTL (default is LTR) |
| twoSided | boolean | Sets Single elimination to be two sided if true. Default is False |
| roundClassName | string | Round wrapper className |
| bracketClassName | string | The bracket className |
| renderSeedComponent | functional component | Custom render for every seed |
| roundTitleComponent | functional component | Custom render for every round title |
| swipeableProps | SwipeableProps | Please check this React Swipeable Views |
For detailed examples, you can clone this repo then:
you can skip starting the root folder, but if you want to modify the library you have to run it.
yarn
then
yarn start
then open a new terminal
cd example
then
yarn
lastly
yarn start
MIT © mohammadou1
Originally created by mohux. This fork is maintained and published as @oliverlooney/react-brackets.
npm rm react-bracketsnpm i @oliverlooney/react-bracketsFAQs
React component to render dynamic bracket UI
The npm package @oliverlooney/react-brackets receives a total of 333 weekly downloads. As such, @oliverlooney/react-brackets popularity was classified as not popular.
We found that @oliverlooney/react-brackets demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket won two 2026 Reppy Awards from RepVue, ranking in the top 5% of all sales orgs. AE Alexandra Lister shares what it's like to grow a sales career here.

Security News
NIST will stop enriching most CVEs under a new risk-based model, narrowing the NVD's scope as vulnerability submissions continue to surge.

Company News
/Security News
Socket is an initial recipient of OpenAI's Cybersecurity Grant Program, which commits $10M in API credits to defenders securing open source software.