npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@paraspatankar/f1js

v1.0.3

Published

TypeScript SDK for Formula 1 data — race results, standings, and telemetry

Readme

f1js

TypeScript SDK for Formula 1 data — race results, standings, drivers, and live telemetry.

npm version license node build tests

f1js wraps Jolpica-F1 and OpenF1 into a single ergonomic API with built-in disk caching, automatic rate limiting, and full TypeScript type safety. No API keys required.


Contents


Installation

npm install @paraspatankar/f1js

Requires Node.js ≥ 18. Not browser-compatible in v1 — see Limitations.


Quick Start

import { f1 } from '@paraspatankar/f1js'

// Race results — historical data from 1950 to present
const results = await f1.races.getResults(2024, 1)
console.log(results[0])
// { position: 1, driverId: 'verstappen', driverCode: 'VER', points: 25, ... }

// Driver telemetry — sampled at ~3.7 Hz (2023+ only)
const carData = await f1.telemetry.getCarData(2024, 1, 'VER')
console.log(carData[0])
// { speed: 312, throttle: 100, brake: false, gear: 8, drs: 12, rpm: 11800, ... }

// Driver championship standings
const standings = await f1.standings.getDriverStandings(2024)
console.log(standings[0])
// { position: 1, driverId: 'verstappen', points: 575, wins: 19, ... }

// Lap time utilities
const gap = f1.utils.lapGap('1:23.456', '1:23.891') // → '+0.435'

API Reference

All methods return Promises and are fully typed. Every data shape is exported from the package — see Type Reference.

Races

Data sourced from Jolpica-F1. Historical coverage from 1950 to present.

// All races in a season, ordered by round number
const races = await f1.races.getSeason(2024)
// → Race[]

// Full results for a specific race round
const results = await f1.races.getResults(2024, 1)
// → RaceResult[]

Race fields: season, round, name, circuit, country, date

RaceResult fields: position, driverId, driverCode, constructorId, constructorName, grid, points, laps, status, fastestLapTime


Drivers

// All drivers who competed in a season
const drivers = await f1.drivers.getSeason(2024)
// → Driver[]

// A single driver by their Jolpica ID (lowercase slug)
const driver = await f1.drivers.getDriver('norris')
// → Driver

Driver fields: driverId, firstName, lastName, code, number, nationality

Common driver IDs: 'verstappen', 'hamilton', 'norris', 'leclerc', 'sainz'


Standings

// Driver championship table for a season
const driverStandings = await f1.standings.getDriverStandings(2024)
// → DriverStanding[]

// Constructor championship table for a season
const constructorStandings = await f1.standings.getConstructorStandings(2024)
// → ConstructorStanding[]

If called with the current season, returns standings as of the most recent race.

DriverStanding fields: position, points, wins, driverId, driverCode, firstName, lastName, constructorId, constructorName

ConstructorStanding fields: position, points, wins, constructorId, constructorName, nationality


Telemetry (2023+)

Data sourced from OpenF1 at ~3.7 Hz. All telemetry methods will throw if season < 2023.

The driver parameter accepts any of:

  • Driver code: 'VER', 'HAM', 'NOR'
  • Last-name slug: 'verstappen', 'hamilton', 'norris'
  • Number: 1, 44, 4
// Car telemetry — ~8,000 samples per driver per race
const carData = await f1.telemetry.getCarData(2024, 1, 'VER')
// → CarData[]

// Lap-by-lap timing (omit driver for all drivers)
const laps = await f1.telemetry.getLapTimes(2024, 1, 'NOR')
// → LapTime[]

// Pit stop events with full pit lane duration
const pitStops = await f1.telemetry.getPitStops(2024, 1)
// → PitStop[]

// Tyre stints — compound, lap range, and tyre age
const stints = await f1.telemetry.getStints(2024, 1, 'HAM')
// → Stint[]

// Race position samples over time (for position-change charts / replays)
const positions = await f1.telemetry.getPositions(2024, 1, 1)
// → Position[]

// Weather readings (~1 per minute, no driver parameter)
const weather = await f1.telemetry.getWeather(2024, 1)
// → WeatherSample[]

Note: The first call for a race fetches from the network and may take several seconds due to response size. All subsequent calls are instant (filesystem cache).


Utilities

Pure functions — no async, no network.

// Parse a lap time string to milliseconds
f1.utils.parseLapTime('1:23.456')        // → 83456

// Format milliseconds back to a lap time string
f1.utils.formatLapTime(83456)            // → '1:23.456'

// Calculate the gap between two lap times
f1.utils.lapGap('1:23.456', '1:23.891') // → '+0.435'
f1.utils.lapGap('1:23.891', '1:23.456') // → '-0.435'

The expected format for parseLapTime and lapGap is M:SS.mmm (e.g. 1:23.456). An error is thrown for invalid formats.


Caching

Results are cached automatically to disk in .f1js-cache/ in your working directory. The cache is keyed by URL, so each unique request is only ever fetched once per policy window.

| Data type | Cache duration | |-----------|---------------| | Past seasons (before current year) | Forever — fetched once, never re-fetched even across restarts | | Current season | 5 minutes |

Add .f1js-cache/ to your .gitignore:

echo ".f1js-cache/" >> .gitignore

Rate Limiting

OpenF1 enforces a hard limit of 3 requests/second. f1js handles this transparently with a built-in sliding-window queue — you don't need to add any delays or retry logic in your code.

Be aware that the first fetch of full-race telemetry (up to ~35,000 samples across all drivers) can take a meaningful amount of time as requests are queued. Subsequent calls are instant thanks to the cache.


Type Reference

All types are exported from the package top-level and can be imported directly:

import type {
  Race,
  RaceResult,
  Driver,
  DriverStanding,
  ConstructorStanding,
  CarData,
  Stint,
  Position,
} from '@paraspatankar/f1js'

| Type | Source | Description | |------|--------|-------------| | Race | Jolpica | A scheduled race event | | RaceResult | Jolpica | One driver's result in a race | | Driver | Jolpica | Driver profile and metadata | | DriverStanding | Jolpica | Championship position for a driver | | ConstructorStanding | Jolpica | Championship position for a constructor | | CarData | OpenF1 | A single telemetry sample (speed, throttle, brake, RPM, gear, DRS) | | LapTime | OpenF1 | One lap's timing data for a driver | | PitStop | OpenF1 | A pit stop event with full pit lane duration | | Stint | OpenF1 | A tyre stint (compound, lap range, tyre age) | | Position | OpenF1 | A race position snapshot for a driver at a point in time | | WeatherSample | OpenF1 | Air temp, track temp, humidity, wind, rainfall |


Limitations

  • Telemetry is 2023+ only. OpenF1 does not have data before the 2023 season. For historical lap times, use f1.races.getResults() instead.
  • Node.js only in v1. The disk cache uses fs/promises, which isn't available in browsers. Attempting to bundle f1js for the browser will fail at this import. A dual-build with an isomorphic in-memory cache fallback is planned for v2.
  • No live telemetry in v1. This library targets historical and completed sessions. Live race data (WebSocket streaming) is on the roadmap for v2.
  • Not for data science. If you're doing lap time analysis in Python, FastF1 is a better fit. f1js targets web developers building Node.js applications.

Data Sources

Both APIs are free and require no authentication.

| Source | Coverage | Documentation | |--------|----------|---------------| | Jolpica-F1 | Results, standings, schedules (1950–present) | ergast.com/mrd | | OpenF1 | Car telemetry at ~3.7 Hz (2023–present) | openf1.org/documentation |


Contributing

# Install dependencies
npm install

# Run tests
npm test

# Type check
npm run typecheck

# Build (CJS + ESM + type declarations)
npm run build

# Watch mode for development
npm run dev

Tests are written with Vitest. The test suite covers normalizers, lap time utilities, and basic setup.


License

ISC © Paras Patankar