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

@classic-mp/types

v1.9.0

Published

TypeScript types for the ccmp JavaScript scripting API (server and client).

Downloads

862

Readme

ccmp-types

TypeScript declarations for the CCMP JavaScript scripting API.

Install this package as a development dependency in server scripts, client scripts, or standalone CEF UI bundles to get autocomplete and tsc checking for the runtime-provided globalThis.ccmp object.

This package is declaration-only. Do not import runtime values from it; use import type when you need named TypeScript types.

The package is published publicly on npm. The source repository is private, so package consumers do not need repository access to install or use these types.

Install

npm install -D @classic-mp/types

Subpath Exports

| Subpath | Use it for | Provides | | --- | --- | --- | | @classic-mp/types/server | Server-side scripts | ccmp server global, players, entities, world state, server events | | @classic-mp/types/client | Client-side scripts | ccmp client global, players, browsers, cameras, local peds, GTA natives | | @classic-mp/types/ui | CEF/browser UI bundles | Minimal UI bridge global exposed as ccmp and window.ccmp | | @classic-mp/types/natives | Advanced native typing | Standalone GTA V native interfaces |

Use either /server or /client in one script project, not both. They both declare the same global name (ccmp) with different shapes.

Server Scripts

Add the server subpath to compilerOptions.types:

// tsconfig.json
{
  "compilerOptions": {
    "types": ["@classic-mp/types/server"],
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true
  },
  "include": ["**/*.ts", "**/*.js", "**/*.d.ts"]
}

The runtime provides ccmp globally, so regular scripts do not need an import.

ccmp.world.weather = 'EXTRASUNNY';
ccmp.world.hour = 12;

ccmp.on('playerConnected', (player) => {
  player.teleport(90.79, -1951.33, 20.74, 307.23);
  player.giveWeapon(ccmp.hash('WEAPON_PISTOL'), 200);

  const vehicle = ccmp.vehicles.create(
    ccmp.hash('adder'),
    94.5,
    -1940.2,
    20.7,
    307.0,
    {
      primaryColor: 27,
      secondaryColor: 111,
      numberPlate: 'CCMP',
      engineOn: true
    }
  );

  if (vehicle) {
    vehicle.dirtLevel = 0;
    vehicle.lockState = 1;
    vehicle.setStreamSyncedMeta('ownerId', player.id);
    player.putIntoVehicle(vehicle.id, -1);
  }

  const guard = ccmp.peds.create(
    ccmp.hash('s_m_y_cop_01'),
    98.0,
    -1944.0,
    20.7,
    180.0,
    {
      health: 250,
      maxHealth: 250,
      armour: 100,
      frozen: true,
      weapon: { hash: ccmp.hash('WEAPON_CARBINERIFLE'), ammo: 90 },
      dimension: player.dimension
    }
  );

  if (guard) {
    guard.accuracy = 65;
    guard.visible = true;
  }
});

ccmp.on('playerDisconnected', (player) => {
  console.log(`${player.name} (${player.id}) disconnected`);
});

Available server managers:

  • ccmp.players: connected players.
  • ccmp.vehicles, ccmp.objects, ccmp.peds: server-spawned world entities.
  • ccmp.markers, ccmp.blips, ccmp.checkpoints, ccmp.colshapes: world helpers and trigger volumes.
  • ccmp.world: authoritative weather and clock state.

Most server-created entities expose id, isExists, mutable world properties, dimension, destroy(), and stream-synced meta helpers.

Server-spawned vehicles, peds, markers, blips, and checkpoints use server-authoritative setters for their supported gameplay and visual properties. Updates are synchronized live to clients currently streaming the entity and included in future stream-in snapshots.

Ped setters cover model/position/heading/health/armour plus visibility, physics flags, alpha, max health, accuracy and one authoritative equipped weapon.

const zone = ccmp.colshapes.createSphere(100, -1900, 21, 3, {
  dimension: 0
});

ccmp.on('playerEnterColshape', (player, colshape) => {
  if (!colshape || colshape.id !== zone?.id) return;

  player.emit('hud:toast', {
    text: 'You entered the garage.'
  });
});

Client Scripts

Add the client subpath to compilerOptions.types:

// tsconfig.json
{
  "compilerOptions": {
    "types": ["@classic-mp/types/client"],
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true
  },
  "include": ["**/*.ts", "**/*.js", "**/*.d.ts"]
}

The client API includes player state, CEF browsers, cameras, local-only peds, connection control, cursor control, nametags, GTA natives, notifications, and read-only access to stream-synced entity meta. The client runtime also provides numeric setTimeout/setInterval timer IDs.

const browser = ccmp.browsers.create('package://ui/index.html');

ccmp.on('keyUp', (key) => {
  if (key === 0x50) {
    ccmp.notify('P pressed');
    browser.executeJavaScript('window.dispatchEvent(new Event("ccmp:p"))');
  }
});

ccmp.on('render', () => {
  // Per-frame client work, such as native HUD drawing.
});

const hideHintTimer: number = setTimeout(() => {
  ccmp.notify('Hint expired');
}, 5000);
clearTimeout(hideHintTimer);

ccmp.on('chatMessage', (message) => {
  console.log(`[chat] ${message.authorName}: ${message.text}`);
});

ccmp.on('streamSyncedMetaChange', (change) => {
  if (
    change.entityType === ccmp.entities.ENTITY_TYPE.Vehicle &&
    change.key === 'ownerId'
  ) {
    console.log(`Vehicle ${change.entityId} owner changed`, change.newValue);
  }
});

const local = ccmp.players.local;
if (local) {
  const faction = local.getStreamSyncedMeta<string>('faction');
  console.log('Local faction:', faction);
}

Client-only helpers are typed too:

const camera = ccmp.cameras.create(
  'garage-preview',
  { x: 100, y: -1900, z: 24 },
  { x: -15, y: 0, z: 140 },
  60
);

camera.setActive(true);
ccmp.cameras.renderScriptCams(true, true, 500);

const ped = ccmp.peds.create(
  'a_m_m_business_01',
  { x: 102, y: -1902, z: 21 },
  180,
  { dimension: 0 }
);

ccmp.cursor.show();
ccmp.nametags.enabled = false;

CEF UI Bundles

Use the UI subpath for browser-side code that talks to the client script.

// tsconfig.json
{
  "compilerOptions": {
    "types": ["@classic-mp/types/ui"],
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "lib": ["ES2022", "DOM"]
  },
  "include": ["src/**/*"]
}
ccmp.emitClient('ui:ready', {
  at: Date.now()
});

ccmp.emitServer('garage:buyVehicle', {
  model: 'adder'
});

const off = ccmp.on('hud:update', (data) => {
  console.log('HUD update from client script:', data);
});

off();

Typing Custom Events

Built-in events are typed out of the box. Project-specific events are typed through declaration merging in a .d.ts file that is included by your tsconfig.json.

Server-side declaration:

// src/ccmp-events.d.ts
import '@classic-mp/types/server';

declare module '@classic-mp/types/server' {
  interface CcmpServerEvents {
    teleportRequest: {
      x: number;
      y: number;
      z: number;
      heading?: number;
    };
  }

  interface CcmpClientInboundEvents {
    'hud:toast': {
      text: string;
    };
  }
}
ccmp.on('teleportRequest', (player, data) => {
  player.teleport(data.x, data.y, data.z, data.heading);
  player.emit('hud:toast', { text: 'Teleported.' });
});

Client-side declaration:

// src/ccmp-events.d.ts
import '@classic-mp/types/client';

declare module '@classic-mp/types/client' {
  interface CcmpClientEvents {
    'hud:toast': {
      text: string;
    };
    'ui:ready': {
      at: number;
    };
  }

  interface CcmpServerInboundEvents {
    teleportRequest: {
      x: number;
      y: number;
      z: number;
      heading?: number;
    };
  }
}
ccmp.on('hud:toast', (payload) => {
  ccmp.notify(payload.text);
});

ccmp.emitServer('teleportRequest', {
  x: 90.79,
  y: -1951.33,
  z: 20.74
});

UI-side declaration:

// src/ccmp-events.d.ts
import '@classic-mp/types/ui';

declare module '@classic-mp/types/ui' {
  interface CcmpClientInboundEvents {
    'ui:ready': {
      at: number;
    };
  }

  interface CcmpServerInboundEvents {
    'garage:buyVehicle': {
      model: string;
    };
  }
}

Stream-Synced Meta

Server entities that implement StreamSyncedMeta can store JSON-compatible values that are automatically replicated to clients currently streaming the entity and included in future stream-in snapshots.

vehicle.setStreamSyncedMeta('locked', true);
vehicle.setStreamSyncedMeta('fuel', 42.5);

const fuel = vehicle.getStreamSyncedMeta<number>('fuel');
vehicle.deleteStreamSyncedMeta('locked');

Clients observe this data read-only:

function isVehicleLocked(vehicleId: number): boolean {
  return (
    ccmp.entities.getStreamSyncedMeta<boolean>(
      ccmp.entities.ENTITY_TYPE.Vehicle,
      vehicleId,
      'locked'
    ) ?? false
  );
}

ccmp.on('streamSyncedMetaChange', (change) => {
  console.log(change.entityType, change.entityId, change.key, change.newValue);
});

Checking Your Project

npx tsc --noEmit -p tsconfig.json

Run TypeScript in your script or UI project after adding the relevant subpath to compilerOptions.types.

Versioning

@classic-mp/[email protected] tracks CCMP runtime API compatibility by major/minor version. Patch releases fix declaration bugs without requiring runtime API changes.

Maintainers

The source repository is private. Maintainers can validate declaration changes locally before release:

npm run check

Releases are published to npm as @classic-mp/types.

License

MIT