<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chesstiny</title>
    <description>The latest articles on DEV Community by Chesstiny (@chesstiny).</description>
    <link>https://dev.to/chesstiny</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3780041%2F8a873e5d-924c-4463-bd08-9681d3e21755.jpg</url>
      <title>DEV Community: Chesstiny</title>
      <link>https://dev.to/chesstiny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chesstiny"/>
    <language>en</language>
    <item>
      <title>Beyond the Bracket: Building a High-Performance Tournament Engine with Go and WebAssembly</title>
      <dc:creator>Chesstiny</dc:creator>
      <pubDate>Wed, 18 Feb 2026 18:22:17 +0000</pubDate>
      <link>https://dev.to/chesstiny/beyond-the-bracket-building-a-high-performance-tournament-engine-with-go-and-webassembly-cie</link>
      <guid>https://dev.to/chesstiny/beyond-the-bracket-building-a-high-performance-tournament-engine-with-go-and-webassembly-cie</guid>
      <description>&lt;p&gt;&lt;strong&gt;Subtitle:&lt;/strong&gt; How the need for complex chess tournaments led to creating Tourney—an open-source, cross-platform library for managing competition state.&lt;/p&gt;




&lt;h3&gt;
  
  
  The "Simple" Problem of Tournaments
&lt;/h3&gt;

&lt;p&gt;While building my upcoming chess platform, &lt;strong&gt;Chesstiny&lt;/strong&gt;, I hit a deceptively complex engineering hurdle: managing tournaments.&lt;/p&gt;

&lt;p&gt;On the surface, a tournament seems simple. It’s just a bracket, right? Team A plays Team B, the winner moves on.&lt;/p&gt;

&lt;p&gt;But when you actually sit down to model this in software, the state management becomes a nightmare. You have to track:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different stages (groups vs. knockouts).&lt;/li&gt;
&lt;li&gt;Dynamic progression (the player in "Round 2, Match 3, Slot 1" isn't known until "Round 1, Match 5" finishes).&lt;/li&gt;
&lt;li&gt;Scoring rules, tie-breakers, and leaderboards.&lt;/li&gt;
&lt;li&gt;The status of every individual game (scheduled, ongoing, settled).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trying to manage this state with ad-hoc database queries and spaghetti code is a recipe for disaster. I needed a robust, dedicated engine to handle the business logic of competition. I wanted something fast enough for a serverless backend, but portable enough to run entirely in the client's browser for a snappy user experience.&lt;/p&gt;

&lt;p&gt;Existing solutions didn't fit the bill. So, I engineered my own.&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;Tourney&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is Tourney?
&lt;/h3&gt;

&lt;p&gt;Tourney is an open-source tournament management library designed to handle the entire lifecycle of a competition structure. It models the hierarchy of tournaments, draws (rounds), matches, games, players, and scores with a strict, clean type system.&lt;/p&gt;

&lt;p&gt;It is not a front-end bracket visualization library (though it pairs well with them). It is the &lt;strong&gt;logic engine&lt;/strong&gt; underneath that decides who plays whom next based on the results you feed it.&lt;/p&gt;

&lt;p&gt;What makes Tourney unique is its hybrid architecture, designed for modern full-stack development.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Architecture: Go Core, WASM Everywhere
&lt;/h3&gt;

&lt;p&gt;To get the performance and reliability I needed for Chesstiny, I made a specific architectural choice: &lt;strong&gt;Write once in Go, run anywhere via WebAssembly.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. The Go Core (The Brain)
&lt;/h4&gt;

&lt;p&gt;The heavy lifting—the complex state transitions, the progression logic, leaderboard sorting—is all written in native Go. Go is perfect for this: it’s strongly typed, performant, and excellent at modeling complex data structures.&lt;/p&gt;

&lt;p&gt;If you are a Go developer, you can import the core package directly into your backend services.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. The WebAssembly Bridge (The Portability)
&lt;/h4&gt;

&lt;p&gt;This is where it gets interesting. To make this logic available to frontend JavaScript/TypeScript developers (and Node.js serverless environments), the Go core is compiled into a WebAssembly (WASM) binary.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. The TypeScript Wrapper (The DX)
&lt;/h4&gt;

&lt;p&gt;Nobody wants to manually invoke exported WASM functions in their daily workflow.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;tourney&lt;/code&gt; npm package provides an idiomatic TypeScript wrapper around the WASM binary. It handles the initialization of the WASM runtime and provides fully typed classes and methods. As a consumer of the library, you never feel like you are interacting with a binary; it just feels like a standard, robust TypeScript library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// It feels like standard TS, but it's running Go under the hood.&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TournamentWasm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@olaoluwanhs/tourney&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tournament&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TournamentWasm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Chess Championship 2026&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scheduled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;tournament&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Add a round with 4 matches&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Killer Feature: Cross-Draw Progression
&lt;/h3&gt;

&lt;p&gt;The hardest part of tournament logic is handling progression in multi-stage events (like knockouts).&lt;/p&gt;

&lt;p&gt;How do you define a match in the semi-finals before the quarter-finals have been played? You don't know &lt;em&gt;who&lt;/em&gt; the players are yet.&lt;/p&gt;

&lt;p&gt;Tourney solves this with &lt;strong&gt;Position References&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of assigning a specific user ID to a match slot, you can assign a reference string like &lt;code&gt;"1-match_abc123"&lt;/code&gt;. This translates to: &lt;em&gt;"The player who finished 1st (the winner) in match &lt;code&gt;abc123&lt;/code&gt;."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When you call the &lt;code&gt;progress()&lt;/code&gt; method on the tournament, the engine—running deep inside the WASM binary—scans previous results, resolves these references to actual user IDs, and updates the tournament state automatically.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Built-in Developer UI
&lt;/h3&gt;

&lt;p&gt;Designing complex tournament structures via code can be mentally taxing. You often need to visualize the tree to understand if your progression logic is sound.&lt;/p&gt;

&lt;p&gt;To solve this developer experience hurdle, the npm package ships with a built-in visual tool. By running a simple command, you launch a local server that provides a drag-and-drop interface (built with React Flow) to design, test, and inspect your tournament structures visually.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @olaoluwanhs/tourney launch-ui

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can build out your bracket visually, verify the progression paths, and then export the resulting JSON structure to use in your actual application.&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;Try it out in your JavaScript/TypeScript project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @olaoluwanhs/tourney

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the "Hello World" of creating a tournament and adding a match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TournamentWasm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@olaoluwanhs/tourney&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Initialize WASM (only needed once if using progression features)&lt;/span&gt;
  &lt;span class="c1"&gt;// Ensure tournament.wasm and wasm_exec.js are in your public assets folder&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TournamentWasm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initWasm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;wasmUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/tournament.wasm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="na"&gt;wasmExecUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/wasm_exec.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Create the tournament container&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TournamentWasm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My First Tourney&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scheduled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// 3. Add a draw (round) expecting 2 matches&lt;/span&gt;
  &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drawId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;draws&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 4. Add a specific match to that draw expecting 2 players&lt;/span&gt;
  &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMatchToDraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;drawId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gameId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;draws&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// 5. Add real players&lt;/span&gt;
  &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPlayerToGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gameId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Alice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPlayerToGame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gameId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tournamentObject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Tourney was born out of necessity for &lt;strong&gt;Chesstiny&lt;/strong&gt;, and it will continue to evolve as that platform grows. I’m excited to open-source it today so other developers building esports platforms, sports apps, or community gaming tools don't have to reinvent this particular wheel.&lt;/p&gt;

&lt;p&gt;I’d love for you to give it a spin and let me know what you think.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 &lt;strong&gt;NPM:&lt;/strong&gt; &lt;a href="https://www.google.com/search?q=%5Bhttps://www.npmjs.com/package/%40olaoluwanhs/tourney%5D(https://www.npmjs.com/package/%40olaoluwanhs/tourney)" rel="noopener noreferrer"&gt;&lt;code&gt;@olaoluwanhs/tourney&lt;/code&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;💻 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://www.google.com/search?q=https://github.com/olaoluwanhs/Tourney" rel="noopener noreferrer"&gt;olaoluwanhs/Tourney&lt;/a&gt; (Star s are greatly appreciated!)&lt;/li&gt;
&lt;li&gt;♟️ &lt;strong&gt;Chesstiny:&lt;/strong&gt; Coming soon!&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>webassembly</category>
    </item>
  </channel>
</rss>
