Hey there! This is the IGDB Wrapper, your new best friend for talking to The Internet Games Database (IGDB) API in TypeScript. We built it to be super powerful and really smart about types, making your life a whole lot easier.
- Type-Safe Queries, Always: Forget about pesky runtime errors. We'll catch your field name mistakes and query structure hiccups before you even hit run. It's validation at compile-time, so you can build with confidence.
- Seriously Smart Typing: This isn't just basic TypeScript support. We're talking full generics and conditional types that intelligently figure out the data types based on the fields you actually request.
- Fluent Query Builder: Craft complex IGDB queries like you're writing a sentence. Our API lets you chain methods elegantly, making your code readable and your queries powerful.
- Blazing Fast Performance: Only grab the data you truly need. Our optimization helps you keep your requests lean and your app snappy.
- Zero Error Worries: Because we catch errors at compile time, you spend less time debugging and more time building awesome stuff.
- Auto Token Management: OAuth tokens can be a pain, right? We handle refreshing them automatically so you don't have to lift a finger.
- Everything Covered: Games, Genres, Companies, Platforms, and more. We've got comprehensive support for all the core IGDB entities.
Picking it up is easy:
# npm
npm install @tdanks2000/igdb-wrapper
# pnpm
pnpm add @tdanks2000/igdb-wrapper
# yarn
yarn add @tdanks2000/igdb-wrapper
# bun
bun add @tdanks2000/igdb-wrapper
Hereβs how you get up and running:
import { IGDB } from '@tdanks2000/igdb-wrapper';
// Initialize with your IGDB API credentials
const igdb = new IGDB({
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
});
// Simple search
const games = await igdb.games.search('The Witcher 3');
Our query builder is where the real magic happens. It's a super fluent and type-safe way to build those tricky IGDB queries:
import { IGDB, IGDBQueryFactory } from '@tdanks2000/igdb-wrapper';
const igdb = new IGDB({
clientId: 'your-client-id',
clientSecret: 'your-client-secret'
});
// Build complex queries with full type safety
const popularActionGames = IGDBQueryFactory.games()
.select('id', 'name', 'rating', 'cover.*', 'genres.*')
.excludeDefaults()
.byGenre(12) // Action genre
.byRating(80)
.sortBy('rating', 'desc')
.limit(10);
// Execute the query
const games = await igdb.games.getGames({
fields: popularActionGames.getOptions().fields as string[],
where: popularActionGames.getOptions().where,
sort: popularActionGames.getOptions().sort as string,
limit: popularActionGames.getOptions().limit,
includeDefaultFields: false,
});
Every entity type has special methods for the stuff you do all the time:
// Games
const gameQuery = IGDBQueryFactory.games()
.byGenre(12) // Filter by genre
.byPlatform(48) // Filter by platform
.byRating(80, 95) // Rating range
.byReleaseDate(1640995200) // After specific date
.byCompany(123, 'developer') // Company involvement
.popular() // Popular games
.recent(30) // Recent games (last 30 days)
.upcoming(); // Upcoming games
// Companies
const companyQuery = IGDBQueryFactory.companies()
.byCountry(840) // US companies
.developers() // Developer companies
.publishers() // Publisher companies
.searchByName('Nintendo');
// Genres
const genreQuery = IGDBQueryFactory.genres()
.byName('Action')
.searchByName('RPG');
// Platforms
const platformQuery = IGDBQueryFactory.platforms()
.byCategory(1) // Console category
.byGeneration(8) // 8th generation
.searchByName('PlayStation');
Just ask for what you need for optimal performance:
// Minimal fields for list views
const gameList = await igdb.games.getGames({
fields: ['id', 'name', 'cover.image_id'],
includeDefaultFields: false,
limit: 20,
});
// Detailed fields for single item views
const gameDetail = await igdb.games.getGame(1942, {
fields: [
'id', 'name', 'summary', 'storyline', 'rating',
'cover.*', 'screenshots.*', 'genres.*', 'platforms.*'
],
includeDefaultFields: false,
});
You can chain tons of conditions and sorting options:
const complexQuery = IGDBQueryFactory.games()
.select('id', 'name', 'rating', 'cover.*')
.excludeDefaults()
.whereAnd(
'rating >= 80',
'first_release_date >= 1640995200', // After 2022-01-01
'genres = 12' // RPG genre
)
.whereOr(
'platforms = 48', // PlayStation 5
'platforms = 49' // Xbox Series X
)
.sortByMultiple(
{ field: 'rating', direction: 'desc' },
{ field: 'first_release_date', direction: 'desc' }
)
.limit(10)
.offset(20);
This is your main client for talking to the IGDB API.
const igdb = new IGDB({
clientId: string,
clientSecret: string
});
Your starting point for creating type-safe query builders.
// Here's what you can build queries for:
IGDBQueryFactory.games() // GameQueryBuilder
IGDBQueryFactory.genres() // GenreQueryBuilder
IGDBQueryFactory.companies() // CompanyQueryBuilder
IGDBQueryFactory.platforms() // PlatformQueryBuilder
// Get all games
await igdb.games.getGames(options);
// Get single game
await igdb.games.getGame(id, options);
// Search games
await igdb.games.searchGames(query, options);
// Get games by IDs
await igdb.games.getGamesByIds(ids, options);
// Specialized methods
await igdb.games.getPopularGames(options);
await igdb.games.getRecentGames(options);
await igdb.games.getUpcomingGames(options);
await igdb.games.getGamesByGenre(genreId, options);
await igdb.games.getGamesByPlatform(platformId, options);
await igdb.genres.getGenres(options);
await igdb.genres.getGenre(id, options);
await igdb.genres.getGenresByIds(ids, options);
await igdb.genres.getAllGenresSorted(options);
await igdb.genres.getGenreBySlug(slug, options);
await igdb.companies.getCompanies(options);
await igdb.companies.getCompany(id, options);
await igdb.companies.searchCompanies(query, options);
await igdb.companies.getCompaniesByIds(ids, options);
await igdb.companies.getAllCompaniesSorted(options);
await igdb.companies.getCompaniesByCountry(countryCode, options);
await igdb.companies.getDeveloperCompanies(options);
await igdb.companies.getPublisherCompanies(options);
.select(...fields) // Add fields to select
.excludeDefaults() // Exclude default fields
.includeDefaults() // Include default fields (default)
.where(condition) // Add WHERE condition
.whereAnd(...conditions) // Add multiple AND conditions
.whereOr(...conditions) // Add multiple OR conditions
.sortBy(field, direction) // Sort by field
.sortByMultiple(...sorts) // Sort by multiple fields
.limit(value) // Set limit
.offset(value) // Set offset
.search(term) // Add search term
.build() // Build query string
.getOptions() // Get query options object
.reset() // Reset query builder
.byGenre(genreId) // Filter by genre
.byPlatform(platformId) // Filter by platform
.byRating(min, max?) // Filter by rating range
.byReleaseDate(start, end?) // Filter by release date
.byCompany(companyId, role) // Filter by company involvement
.popular() // Get popular games
.recent(days) // Get recent games
.upcoming() // Get upcoming games
# Install dependencies
bun install
# Run development version
bun run src/index.ts
# Run advanced typing example
bun run example-advanced-typing.ts
# Type checking
bun run tsc --noEmit
# Linting
bun run biome check .
# For API access, set these:
export TWITCH_CLIENT_ID='your-client-id'
export TWITCH_CLIENT_SECRET='your-client-secret'
# Or, if you leave these unset, it'll run in demo mode (no actual API calls)
// β
This totally works (compiles like a dream!)
.select('id', 'name', 'cover.*', 'genres.*')
// β This will give you a TypeScript error (caught early!)
.select('invalid_field', 'name.*') // Error: 'invalid_field' not assignable
// β
Building queries is completely type-safe
const query = IGDBQueryFactory.games()
.select('id', 'name')
.where('rating >= 80')
.sortBy('name', 'asc'); // Only 'asc' or 'desc' allowed here!
// β Type errors will jump out at compile time
.sortBy('name', 'invalid') // Error: 'invalid' not assignable
// Your responses are perfectly typed based on the entity you're querying!
const games: Game[] = await igdb.games.getGames();
const genres: Genre[] = await igdb.genres.getGenres();
const companies: Company[] = await igdb.companies.getCompanies();
- Be Specific: Use
select()
to ask for only the fields you absolutely need. - Strip Defaults: If you want full control over your field selection,
excludeDefaults()
is your friend. - Keep it Small: Always use
limit()
to avoid hauling in massive amounts of data. - Smart Caching: If you fetch the same stuff a lot, cache it! Your app will thank you.
- Batch It Up: Need multiple items?
getByIds()
is way more efficient than calling for each one individually.
Contributions are super welcome! Feel free to send over a Pull Request.
MIT