You have a SaaS product. Your users sign up, poke around, and some of them come back. You want more of them to come back. Gamification -- XP, levels, leaderboards -- is one of the most effective ways to make that happen, but building it from scratch takes weeks.
This post walks you through adding a complete gamification layer to your app in 10 minutes using EngageFabric's gamification API. By the end, your users will earn XP for actions, level up, and compete on a live leaderboard. Every step has full code you can copy and run.
EngageFabric is a gamification API built for SaaS products. It handles XP calculations, level thresholds, leaderboard rankings, and quest state machines so you can focus on your product, not game infrastructure.
What you will build
Here is what your app will do after following this guide:
- Track user actions as events (e.g. "completed onboarding", "invited a teammate")
- Award XP automatically based on rules you configure
- Level users up when they cross XP thresholds
- Display a live leaderboard showing top users ranked by XP
Four capabilities, one API, ten minutes. Let's go.
Prerequisites
- A JavaScript/TypeScript project (Node.js 18+)
- An EngageFabric account (sign up free during the alpha)
- Your API key and Project ID from the admin console
Step 1: Install the SDK
Add the EngageFabric SDK to your project:
npm install @playpulse/sdkInitialize the client with your credentials:
import { EngageFabric } from '@playpulse/sdk';
const ef = new EngageFabric({
apiKey: process.env.ENGAGEFABRIC_API_KEY,
projectId: process.env.ENGAGEFABRIC_PROJECT_ID,
});Store your API key in environment variables. Never commit it to source code. Use .env files locally and your platform's secrets manager in production.
That's it for setup. The SDK handles authentication, retries, and connection management. You are ready to start tracking events.
Expected result: The SDK connects to EngageFabric's API and is ready to send events. No errors in your console.
Step 2: Configure your project
Before tracking events, define what actions are worth XP and what your level thresholds look like. You can do this through the admin console UI or programmatically via the API.
Define XP rules
Create rules that map user actions to XP rewards:
// Award 50 XP when a user completes onboarding
await ef.rules.create({
name: 'Onboarding Complete',
trigger: { action: 'onboarding_completed' },
actions: [{ type: 'award_xp', amount: 50 }],
});
// Award 25 XP for each teammate invited
await ef.rules.create({
name: 'Teammate Invited',
trigger: { action: 'teammate_invited' },
actions: [{ type: 'award_xp', amount: 25 }],
});
// Award 100 XP for creating a project
await ef.rules.create({
name: 'Project Created',
trigger: { action: 'project_created' },
actions: [{ type: 'award_xp', amount: 100 }],
});Define level thresholds
Set up levels so users feel a sense of progression:
await ef.levels.configure([
{ level: 1, name: 'Newcomer', xpRequired: 0 },
{ level: 2, name: 'Contributor', xpRequired: 100 },
{ level: 3, name: 'Builder', xpRequired: 300 },
{ level: 4, name: 'Achiever', xpRequired: 600 },
{ level: 5, name: 'Champion', xpRequired: 1000 },
]);Create a leaderboard
Set up a leaderboard to rank your users:
await ef.leaderboards.create({
name: 'Top Contributors',
metric: 'xp',
resetPeriod: 'monthly',
maxEntries: 100,
});You only need to run the configuration code once. After that, the rules, levels, and leaderboard persist in your EngageFabric project. You can also configure all of this through the admin console's visual builder at admin.engagefabric.com.
Expected result: Your project now has three XP rules, five levels, and a monthly leaderboard. You can verify this in the admin console under Project Settings.
Step 3: Add your first XP event
Now wire EngageFabric into your application code. Wherever a user performs a meaningful action, track it as an event.
Here is a real-world example -- a user finishes onboarding in your app:
// In your onboarding completion handler
async function completeOnboarding(userId: string) {
// Your existing onboarding logic
await db.user.update({
where: { id: userId },
data: { onboardingComplete: true },
});
// Track the event in EngageFabric (one line)
await ef.events.track({
playerId: userId,
action: 'onboarding_completed',
properties: {
completedAt: new Date().toISOString(),
},
});
}The playerId is your internal user identifier. EngageFabric creates a player profile automatically on the first event -- no separate registration step needed.
What happens behind the scenes
When EngageFabric receives that event, the rules engine kicks in:
- Matches the rule --
onboarding_completedtriggers the "Onboarding Complete" rule - Awards 50 XP to the player
- Checks level threshold -- if the player crosses 100 XP, they level up to "Contributor"
- Updates the leaderboard -- the player's new XP total is reflected in rankings
- Fires webhooks -- your backend can listen for
player.xp_earnedandplayer.leveled_upevents
All of this happens in under 50ms. Your user gets instant feedback.
Track more actions
Add event tracking wherever it makes sense in your app:
// User invites a teammate
await ef.events.track({
playerId: userId,
action: 'teammate_invited',
properties: { inviteeEmail: email },
});
// User creates a project
await ef.events.track({
playerId: userId,
action: 'project_created',
properties: { projectName: name },
});
// User completes a daily login
await ef.events.track({
playerId: userId,
action: 'daily_login',
});Expected result: Open the admin console and navigate to the Players section. You should see your test user with XP awarded and their current level displayed. Each event appears in the player's activity timeline.
Step 4: Display the leaderboard
The final step is showing your users where they stand. EngageFabric provides both pre-built React components and raw data hooks.
Option A: Pre-built components (fastest)
Drop in the React SDK for a working leaderboard in three lines:
npm install @playpulse/reactimport { Leaderboard } from '@playpulse/react';
function LeaderboardPage() {
return (
<Leaderboard
leaderboardId="top-contributors"
limit={10}
showCurrentUser
className="my-leaderboard"
/>
);
}The <Leaderboard /> component renders a ranked list with player names, XP totals, level badges, and position changes. The showCurrentUser prop highlights the logged-in user's row even if they are not in the top 10.
Option B: Build your own UI (full control)
Use the data hooks to fetch leaderboard data and render it however you want:
import { useLeaderboard, usePlayer } from '@playpulse/react';
function CustomLeaderboard() {
const { entries, isLoading } = useLeaderboard('top-contributors', {
limit: 10,
});
const { player } = usePlayer(currentUserId);
if (isLoading) return <div>Loading...</div>;
return (
<div className="space-y-2">
<h2 className="text-xl font-bold">Top Contributors</h2>
<div className="rounded-lg border">
{entries.map((entry, index) => (
<div
key={entry.playerId}
className={`flex items-center justify-between p-3 ${
entry.playerId === currentUserId
? 'bg-blue-50 font-semibold'
: ''
}`}
>
<div className="flex items-center gap-3">
<span className="text-lg font-mono w-8">
#{index + 1}
</span>
<div>
<p>{entry.displayName}</p>
<p className="text-sm text-gray-500">
Level {entry.level} · {entry.levelName}
</p>
</div>
</div>
<span className="font-mono">{entry.xp.toLocaleString()} XP</span>
</div>
))}
</div>
{player && (
<p className="text-sm text-gray-600 mt-4">
Your rank: #{player.leaderboardPosition} ·{' '}
{player.xp.toLocaleString()} XP
</p>
)}
</div>
);
}Add an XP progress bar
While you are at it, show users their progress toward the next level:
import { usePlayer } from '@playpulse/react';
function XPProgressBar({ userId }: { userId: string }) {
const { player, isLoading } = usePlayer(userId);
if (isLoading) return <div className="h-8 bg-gray-100 animate-pulse rounded" />;
const progress = (player.xp / player.nextLevelXp) * 100;
return (
<div className="space-y-1">
<div className="flex justify-between text-sm">
<span className="font-medium">
Level {player.level} — {player.levelName}
</span>
<span className="text-gray-500">
{player.xp} / {player.nextLevelXp} XP
</span>
</div>
<div className="h-3 bg-gray-200 rounded-full overflow-hidden">
<div
className="h-full bg-gradient-to-r from-blue-500 to-indigo-500 rounded-full transition-all duration-500"
style={{ width: `${progress}%` }}
/>
</div>
</div>
);
}Expected result: Your app now shows a live leaderboard with ranked users, XP totals, and level badges. The currently logged-in user sees their position highlighted. The XP progress bar shows how close they are to the next level.
The complete picture
Here is everything you just built, end to end:
User action (e.g. "completed onboarding")
→ ef.events.track()
→ Rules engine matches action to XP rule
→ Player XP updated (+50)
→ Level check (did they level up?)
→ Leaderboard recalculated
→ UI updates via React hooks
Total lines of integration code: ~15 lines in your backend, ~20 lines in your frontend. The rest is handled by EngageFabric.
What to add next
You have a working gamification layer. Here are the highest-impact features to add next:
- Quests -- Guide users through multi-step flows like onboarding or feature discovery. Quest documentation →
- Streaks -- Reward daily engagement with streak counters and multipliers. Streaks documentation →
- Webhooks -- React to game events in your backend for notifications, emails, or custom business logic. Webhooks documentation →
- Analytics -- Track quest completion funnels and retention cohorts in the admin dashboard. Analytics documentation →
The full API reference is at docs.engagefabric.com.