diepAPI is a comprehensive library that gives you programmatic access to the diep.io game. Build powerful bots and tools with just a few lines of code! Whether you want to create an AFK script, automate shape farming, or build advanced analytics tools, diepAPI makes it easy.
Key capabilities:
- 🎮 Real-time game state - Access player position, velocity, level, tank type, and more
- 🤖 Player control - Move, aim, shoot, and upgrade programmatically
- 👁️ Entity tracking - Track all visible players, shapes, and projectiles
- 🎨 Canvas overlays - Draw custom visualizations on top of the game
- ⚡ Event-driven - React to game events like spawning, leveling up, and frame updates
- 📘 TypeScript support - Full type definitions included
You don't need to install diepAPI separately! Just add a @require directive to your userscript, and your userscript manager will automatically load diepAPI for you.
Create a new userscript in Tampermonkey/Violentmonkey with:
// ==UserScript==
// @name My Awesome Bot
// @description My custom diep.io bot
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @grant none
// ==/UserScript==
// diepAPI is automatically loaded and available here!
const { game, player } = diepAPI.apis;
game.on('ready', () => {
console.log('Bot started!');
player.spawn('MyBot');
});That's it! The @require line automatically downloads and loads diepAPI before your script runs.
Requirements: Tampermonkey or Violentmonkey
If you want to experiment with diepAPI directly in the browser console without writing a script:
- Install Tampermonkey or Violentmonkey
- Download
diepAPI.user.jsfrom Releases - Install it in your userscript manager
- Navigate to diep.io
- Open browser console and use
window.diepAPI
This method is mainly for testing and experimentation. For building bots, use the @require method above.
See the Building from Source section below.
Here's a complete, ready-to-use example. Copy this entire code block and create a new userscript in your userscript manager:
// ==UserScript==
// @name Position Logger
// @description Logs player position every frame
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @grant none
// ==/UserScript==
// Access the APIs you need
const { game, player } = diepAPI.apis;
// Wait for the game to be ready
game.on('ready', () => {
console.log('diepAPI is ready!');
// Spawn with a custom name
player.spawn('MyBot');
});
// Run code every frame
game.on('frame', () => {
// Access player state
console.log('Position:', player.position);
console.log('Velocity:', player.velocity);
console.log('Level:', player.level);
});How to use:
- Copy the code above
- In Tampermonkey/Violentmonkey, click "Create new script"
- Paste the code and save
- Navigate to diep.io
- Open browser console (F12) to see the logs
The @require directive automatically downloads diepAPI - no separate installation needed!
diepAPI is organized into three main namespaces:
-
diepAPI.apis- Core game APIs for accessing state and controlling the playergame,player,input,arena,camera,scaling,minimap,playerMovement
-
diepAPI.extensions- Optional features that must be loaded before useentityManager(track all visible entities),debugTool(visual debugging)
-
diepAPI.tools- Utility tools for drawing and visualizationoverlay(canvas overlay),backgroundOverlay(background canvas)
-
diepAPI.core- Core utilities likeVectormath
diepAPI uses an event-driven architecture. Subscribe to events to react to game state changes:
const { game, player } = diepAPI.apis;
// Game events
game.on('ready', () => console.log('Game is ready!'));
game.on('before_frame', () => console.log('Before frame'));
game.on('frame_start', () => console.log('Frame started'));
game.on('frame', () => console.log('New frame'));
game.on('frame_end', () => console.log('Frame ended'));
game.on('after_frame', () => console.log('After frame'));
// Player events
player.on('spawn', () => console.log('Player spawned'));
player.on('dead', () => console.log('Player died'));
player.on('level', (level) => console.log('Level up!', level));
player.on('tank', (tankType) => console.log('Tank changed:', tankType));Remove event listeners with .off():
const handler = () => console.log('Frame');
game.on('frame', handler);
game.off('frame', handler); // Remove listenerdiepAPI works with three coordinate systems:
- Arena coordinates - Game world coordinates (origin at arena center)
- Canvas coordinates - High-DPI canvas rendering coordinates
- Screen coordinates - Browser viewport pixel coordinates
Convert between them using the scaling API:
const { scaling } = diepAPI.apis;
// Convert between coordinate systems
const arenaPos = scaling.toArenaPos(canvasPos);
const canvasPos = scaling.toCanvasPos(arenaPos);
const screenPos = scaling.canvasToScreen(canvasPos);
const canvasPos = scaling.screenToCanvas(screenPos);Extensions must be loaded before use:
const { entityManager } = diepAPI.extensions;
// Load the extension (call once)
entityManager.load();
// Now you can use it
console.log(entityManager.entities);Choose an example based on your experience level:
| Example | Difficulty | What You'll Learn | Install |
|---|---|---|---|
| Press O Script | 🟢 Beginner | Basic events, auto-spawn | |
| AFK Script | 🟢 Beginner | Event handling, player control, movement | |
| Shape Farmer | 🟡 Intermediate | Entity tracking, filtering, targeting | |
| Safe Zone Keeper | 🟡 Intermediate | Position management, boundary logic, vectors |
The simplest possible bot - automatically opens the upgrade menu when you spawn and respawns when you die.
// ==UserScript==
// @name Press O
// @description best script
// @version 0.0.2
// @author Cazka
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @icon https://www.google.com/s2/favicons?domain=diep.io
// @grant none
// ==/UserScript==
const { player } = window.diepAPI.apis;
player.on('spawn', async () => await player.keyPress('o'));
player.on('dead', async () => await player.spawn());What you'll learn:
- Using player events (
spawn,dead) - Auto-spawning with
player.spawn() - Simulating key presses with
player.keyPress()
Keep your tank stationary at its current position. Press Q to toggle AFK mode on/off.
// ==UserScript==
// @name AFK Script
// @description press Q to activate AFK
// @version 0.0.5
// @author Cazka
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @icon https://www.google.com/s2/favicons?domain=diep.io
// @grant none
// ==/UserScript==
const { Vector } = window.diepAPI.core;
const { player, game } = window.diepAPI.apis;
let afkActive = false;
let afkPosition;
// Toggle AFK mode with Q key
window.addEventListener('keydown', (e) => {
if (e.code != 'KeyQ') return;
// Toggle AFK state
afkActive = !afkActive;
// Enable/disable API control of player movement
// (prevents user keyboard input from interfering)
player.useGamepad(afkActive);
// Save current position when activating AFK
if (afkActive) afkPosition = player.position;
});
// Every frame, move back to the saved position
game.on('frame', () => {
if (!afkActive) return;
// Move player to the saved AFK position
player.moveTo(afkPosition);
});What you'll learn:
- Basic event handling with keyboard and game events
- Using
player.useGamepad()to enable API control - Using
player.moveTo()to control player position - Toggle pattern for activating/deactivating features
Automatically aims at nearby shapes and shoots them. Press P to toggle farming mode on/off.
// ==UserScript==
// @name Farm Script
// @description press P to start the farmer
// @version 0.0.7
// @author Cazka
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @icon https://www.google.com/s2/favicons?domain=diep.io
// @grant none
// ==/UserScript==
const { Vector } = window.diepAPI.core;
const { player, game } = window.diepAPI.apis;
const { entityManager } = window.diepAPI.extensions;
// Load the entity manager extension to track entities
entityManager.load();
let farmActive = false;
// Toggle farming mode with P key
window.addEventListener('keydown', (e) => {
if (e.code != 'KeyP') return;
farmActive = !farmActive;
});
// Every frame, find and aim at the nearest shape
game.on('frame', () => {
if (!farmActive) return;
// Filter entities to find shapes only
// Entity types: 0-3 are players/projectiles, 4+ are shapes
// Type 9 is Alpha Pentagon (too dangerous), so we exclude it
const entities = entityManager.entities.filter((x) => x.type > 3 && x.type !== 9);
if (entities.length === 0) {
return; // No shapes nearby
}
// Find the closest shape using reduce
const entity = entities.reduce((acc, x) => {
// Use predictPos() to account for entity movement
// This gives better accuracy when entities are moving
const distAcc = Vector.distance(acc.predictPos(100), player.predictPos(100));
const distX = Vector.distance(x.predictPos(100), player.predictPos(100));
// Return whichever entity is closer
return distX < distAcc ? x : acc;
});
// Aim at the closest shape
if (entity) player.lookAt(entity.position);
});What you'll learn:
- Loading and using the
entityManagerextension - Filtering entities by type to find specific targets
- Using
Vector.distance()for distance calculations - Using
predictPos()for better targeting of moving entities - Using
player.lookAt()to aim at targets - Using
reduce()to find the closest entity
Automatically keeps your tank within a safe radius from the arena center. Press Z to toggle safe zone mode on/off. Includes visual boundary overlay.
// ==UserScript==
// @name Safe Zone Keeper
// @description press Z to activate safe zone mode
// @version 0.0.1
// @author Cazka
// @match https://diep.io/*
// @require https://github.com/Cazka/diepAPI/releases/latest/download/diepAPI.user.js
// @icon https://www.google.com/s2/favicons?domain=diep.io
// @grant none
// ==/UserScript==
const { Vector } = window.diepAPI.core;
const { player, game, scaling } = window.diepAPI.apis;
const { overlay } = window.diepAPI.tools;
// Safe zone configuration
const SAFE_ZONE_RADIUS = 1000; // units from arena center
const ARENA_CENTER = new Vector(0, 0);
let safeZoneActive = false;
// Toggle safe zone mode with Z key
window.addEventListener('keydown', (e) => {
if (e.code != 'KeyZ') return;
// Toggle safe zone state
safeZoneActive = !safeZoneActive;
// Enable/disable API control of player movement
player.useGamepad(safeZoneActive);
console.log(`Safe Zone ${safeZoneActive ? 'activated' : 'deactivated'}`);
});
// Every frame, check if player is outside safe zone
game.on('frame', () => {
// Draw safe zone boundary (always visible)
drawSafeZoneBoundary();
if (!safeZoneActive || player.isDead) return;
// Calculate distance from arena center
const distanceFromCenter = Vector.distance(player.position, ARENA_CENTER);
// If player is outside safe zone, move back toward center
if (distanceFromCenter > SAFE_ZONE_RADIUS) {
// Calculate direction vector toward center
const directionToCenter = Vector.subtract(ARENA_CENTER, player.position);
// Normalize the direction vector (make it length 1)
const magnitude = Vector.len(directionToCenter);
const normalized = Vector.scale(directionToCenter, 1 / magnitude);
// Move player toward center
// Using a small step to make movement smooth
const targetPos = Vector.add(player.position, Vector.scale(normalized, 50));
player.moveTo(targetPos);
}
});
// Draw the safe zone boundary circle on the overlay
function drawSafeZoneBoundary() {
const ctx = overlay.ctx;
// Convert arena center to canvas coordinates
const centerCanvas = scaling.toCanvasPos(ARENA_CENTER);
// Convert radius to canvas units
const radiusCanvas = scaling.toCanvasUnits(new Vector(SAFE_ZONE_RADIUS, 0)).x;
ctx.save();
// Draw boundary circle
ctx.strokeStyle = safeZoneActive ? '#00ff00' : '#ffff00';
ctx.lineWidth = 3 * window.devicePixelRatio;
ctx.setLineDash([10, 10]);
ctx.beginPath();
ctx.arc(centerCanvas.x, centerCanvas.y, radiusCanvas, 0, 2 * Math.PI);
ctx.stroke();
// Draw status text
const fontSize = 18 * window.devicePixelRatio;
ctx.font = `${fontSize}px Ubuntu`;
ctx.fillStyle = safeZoneActive ? '#00ff00' : '#ffff00';
ctx.strokeStyle = '#000000';
ctx.lineWidth = fontSize / 8;
ctx.setLineDash([]);
const statusText = `SAFE ZONE: ${safeZoneActive ? 'ON' : 'OFF'}`;
ctx.strokeText(statusText, 20, 40);
ctx.fillText(statusText, 20, 40);
ctx.restore();
}What you'll learn:
- Position management and distance calculations with
Vector.distance() - Boundary detection and response logic
- Normalizing vectors using
Vector.len()andVector.scale()for directional movement - Using
Vector.subtract()andVector.add()for vector operations - Converting between coordinate systems with
scaling.toCanvasPos()andscaling.toCanvasUnits() - Drawing custom visualizations with the
overlaytool - Combining multiple APIs (
player,game,scaling,overlay)
Quick reference for the main APIs:
| API | Description | Key Properties/Methods |
|---|---|---|
| game | Game state and events | .on(event, handler), .off(event, handler), .isReady |
| player | Player state and control | .position, .velocity, .level, .tank, .isDead, .spawn(name), .moveTo(pos), .lookAt(pos), .upgrade_stat(stat, amount), .upgrade_tank(choice), .useGamepad(enabled) |
| input | Keyboard and mouse control | .keyDown(key), .keyUp(key), .keyPress(key), .mouse(x, y), .mousePress(button) |
| arena | Arena information | .size (arena dimensions) |
| camera | Camera position tracking | .position (current camera position) |
| scaling | Coordinate system conversion | .toArenaPos(canvasPos), .toCanvasPos(arenaPos), .screenToCanvas(screenPos), .canvasToScreen(canvasPos) |
| minimap | Minimap position tracking | .position (minimap position) |
| playerMovement | Advanced movement tracking | Position/velocity tracking with prediction |
Extensions must be loaded with .load() before use:
| Extension | Description | Usage |
|---|---|---|
| entityManager | Track all visible entities (players, shapes, projectiles) | .load(), .entities (array), .getPlayer() (get your player entity) |
| debugTool | Visual debugging overlays for development | .load(), .enable(), .disable() |
| Tool | Description | Usage |
|---|---|---|
| overlay | Canvas overlay for drawing custom graphics | .ctx (CanvasRenderingContext2D) |
| backgroundOverlay | Background layer overlay | .ctx (CanvasRenderingContext2D) |
| Utility | Description | Key Methods |
|---|---|---|
| Vector | Vector math operations | .add(), .subtract(), .scale(), .distance(), .magnitude(), .normalize() |
Game Events:
ready- Fired when diepAPI is ready to usebefore_frame- Fired before the game frame startsframe_start- Fired at the start of each frame (used internally for setup)frame- Fired every game frame after game logic is processedframe_end- Fired at the end of each frame (used internally for cleanup)after_frame- Fired after the game frame ends
Player Events:
spawn- Fired when the player spawnsdead- Fired when the player dieslevel- Fired when the player levels up (callback receives level number)tank- Fired when the player changes tank (callback receives tank type)keydown- Fired when a key is pressedkeyup- Fired when a key is released
When using entityManager, entities have a type property:
- 0-3: Players and player projectiles (bullets, drones, etc.)
- 4: Square
- 5: Triangle
- 6: Pentagon
- 7: Crasher
- 9: Alpha Pentagon
Use entity.type to filter for specific entity types.
For complete API documentation with all methods and properties, visit: 📘 https://cazka.github.io/diepAPI/
Want to modify diepAPI or contribute? Here's how to build it yourself:
# Clone the repository
git clone https://github.com/Cazka/diepAPI.git
cd diepAPI
# Install dependencies
npm install
# Build the userscript
npm run buildOutput: dist/diepAPI.user.js
- Make changes to files in
src/ - Run
npm run buildto compile - Install
dist/diepAPI.user.jsin Tampermonkey - Test your changes at diep.io
- Iterate!
npm run lint- Check code style with ESLintnpm run build-tools- Compile TypeScript development tools
Contributions are welcome! Whether it's bug reports, feature requests, or code contributions, we'd love your help making diepAPI better.
- Issues & Bug Reports: GitHub Issues
- Pull Requests: Fork the repo, make your changes, and submit a PR
- Code Style: Run
npm run lintbefore submitting to ensure consistent code style
Join our Discord community to:
- 💬 Get help and support from other developers
- 🎨 Share your bots and scripts
- 💡 Discuss new features and ideas
- 🐛 Report bugs and get quick assistance
- 🤝 Connect with the diepAPI community
Showcase your amazing creations built with diepAPI! See what others have made and share your own.
| Project Name | Description | Author | Links |
|---|---|---|---|
| Your project here! | Submit a PR to showcase your project | Your name | Link to your repo/gist |
Want to showcase your project? Submit a PR adding your project to this table! Make sure your project is educational or automation-focused (no cheats/exploits).
A huge thank you to everyone who has contributed to diepAPI! 🎉
- View all contributors: GitHub Contributors
- Want to contribute? Check out the Contributing section above
We appreciate:
- 🐛 Bug reports and fixes
- ✨ New features and improvements
- 📚 Documentation enhancements
- 💡 Ideas and suggestions
diepAPI is licensed under the MIT License. See LICENSE for details.
- 📘 Full Documentation: https://cazka.github.io/diepAPI/
- 💡 Examples: See Complete Examples (categorized by difficulty) or browse all in examples/
- 💬 Discord Community: Join our Discord - Get help, share projects, and connect with developers
- 🐛 Report Issues: GitHub Issues
- ⭐ Star on GitHub: Cazka/diepAPI
Made with ❤️ for the diep.io community
Happy botting! 🤖
