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

@tikron/client

v0.6.0

Published

Browser SDK for Tikron — GameClient (matchmake/joinOrCreate) and Room (send, onStateChange, prediction, clock sync) over PartySocket.

Downloads

1,229

Readme

@tikron/client

The browser client for Tikron — connect to a server-authoritative game room, receive its state, and send intents. Pairs with @tikron/server. It sets binaryType = "arraybuffer" for you (the WebSocket default silently breaks binary delta decode) and auto-sequences your inputs.

npm i @tikron/client

Scaffold a full game (server + client + Cloudflare config) with npx create-tikron my-game.

Join a room

import { GameClient } from "@tikron/client";

interface ArenaState {
  players: Record<string, { x: number; y: number }>;
}

const client = new GameClient(location.host, { party: "arena-room" });
const room = await client.joinOrCreate("lobby");
const myId = room.connectionId;

// The server's authoritative state, pushed on every sync:
room.onStateChange((state) => render(state as ArenaState));

// Send intents — never state. Auto-sequenced for you:
addEventListener("mousemove", (e) => room.send("move", { x: e.clientX, y: e.clientY }));

function render(_state: ArenaState): void {}

The party option must be the kebab-case of the server's Durable Object binding (ArenaRoomarena-room), and every distinct room id is its own isolated room.

Netcode helpers (opt-in)

For .io-style games where you want smooth motion despite latency:

import { InputPredictor, SnapshotBuffer, ClockSync } from "@tikron/client";
  • InputPredictor — apply your inputs locally now, then reconcile (replay still-unacked inputs) when the server ack arrives, so control feels lag-free.
  • SnapshotBuffer — buffer authoritative snapshots and interpolate remote entities between them for smooth movement.
  • ClockSync — estimate server time so client and server share one timeline.
  • withNetworkConditions — wrap a transport with latency/jitter/packet-loss to test your game under bad networks locally.

Smooth rendering for client-authoritative movement

When the client sends its position and the server validates the speed (the shooter model), use RenderPredictor for the local player and EntitySmoother for everyone else. They encode the anti-rubber-band contract: every outgoing position passes through one speed-budget clamp measured over the real elapsed time between sends (an honest client is never rejected), and a server correction rebases the clamp so one rejection can never cascade into a snapback burst.

import { RenderPredictor, EntitySmoother } from "@tikron/client";
// The SAME MotionProfile constant the room validates with — defined once, imported by both sides.
import { PROFILE } from "./shared/profile.js";

const motion = RenderPredictor.fromProfile(spawnPlaceholder, PROFILE);
const smoother = new EntitySmoother();

room.onMessage("rejected", (p) => motion.correct(p as { x: number; y: number }));
room.onStateChange((s) => {
  const me = (s as MyState).players[room.connectionId!];
  if (me) { motion.alive = me.alive; motion.reconcile(me); }
});

setInterval(() => {
  // Budget-clamped — the ONLY value that may go on the wire. Server clock in, so both
  // sides measure the same inter-move delta.
  room.send("move", motion.sendPosition(room.clock.serverNow()));
}, PROFILE.stepMs);

function render(dtMs: number): void {
  const pos = motion.frame(dir.x, dir.y, dtMs); // camera = pos, 1:1, no extra easing
  const seen = new Set<string>();
  for (const [id, p] of remotePlayers) {
    seen.add(id);
    const sm = smoother.update(id, { x: p.x, y: p.y, angle: p.aim }, dtMs);
    // draw sm.x / sm.y / sm.angle
  }
  smoother.prune(seen); // AOI re-entries snap in fresh instead of gliding
}

On the server, resolve moves with resolveMovement from @tikron/sim (partial advance on an over-budget move — never freeze) and reply client.send("rejected", { x, y }). The pure primitives (integrateMove, clampToBudget, decayOffset, applyCorrection, smoothAxis, smoothAngle, followCamera) are exported too.

GameClient options for FPS / high-rate games

const client = new GameClient(location.host, {
  party: "shooter-room",
  stateCodec: ShooterSchema,   // match the room's codec for binary sync
  subtickTimestamps: true,     // stamp each send() with its server-clock time so the room can
                               // rewind lag compensation to the input instant (needs clock sync)
  inputBatchMs: 33,            // coalesce a burst of sends into one frame (~1 tick); needs a 0.2+
                               // @tikron/server (older servers drop multi-input batches)
});

networkConditions (dev-only bad-network simulation) and reconnect (backoff policy) round out the options — see the SDK types.

Key API

GameClient(host, options)joinOrCreate(room, params?) · Room (send(type, payload?), onStateChange, onMessage(type?, handler), onAck, connectionId, connected(), leave()) · InputPredictor · SnapshotBuffer · RenderPredictor · EntitySmoother · ClockSync · withNetworkConditions · createPartySocketTransport · pure render/motion helpers (decayOffset, applyCorrection, smoothAxis, smoothAngle, followCamera, and integrateMove / clampToBudget re-exported from @tikron/sim).

Links & license

tikron.dev · AGENTS.md. Licensed under the Tikron License 1.0 (adapted from FSL-1.1) — converts to Apache-2.0 one year after each release. See LICENSE.