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

fluxer.ts

v0.3.0

Published

Lightweight, TypeScript-first SDK for building Fluxer bots

Downloads

28

Readme

fluxer.ts

Lightweight, TypeScript-first SDK for building Fluxer bots.

  • Small — single package, one dependency (ws), ~60KB compiled
  • TypeScript-first — 870+ lines of type definitions generated from the Fluxer OpenAPI spec
  • Simple API — connect, listen, send — no unnecessary abstractions
  • Built for Fluxer — handles Fluxer-specific gateway behavior (guild properties, v1 gateway protocol)
  • Complete — 94 route builders, 40+ gateway events, 66 convenience methods, 35 permission constants

Install

npm install fluxer.ts

Quick Start

import { Client, GatewayIntents } from 'fluxer.ts';

const client = new Client({
  intents: GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.MessageContent,
});

client.on('ready', (user, guilds) => {
  console.log(`Connected as ${user.username} in ${guilds.length} guilds`);
});

client.on('messageCreate', async (message) => {
  if (message.author.bot) return;

  if (message.content === '!ping') {
    await client.sendMessage(message.channel_id, 'Pong!');
  }
});

client.login('your-bot-token');

Features

Messages

// Send a message
await client.sendMessage(channelId, 'Hello!');

// Send with embeds
await client.sendMessage(channelId, {
  content: 'Check this out',
  embeds: [{ type: 'rich', title: 'My Embed', description: 'Content here', color: 0x7c6fff }],
});

// Reply to a message
await client.replyTo(message, 'Got it!');

// Edit / delete
await client.editMessage(channelId, messageId, 'Updated content');
await client.deleteMessage(channelId, messageId);

// Bulk delete (2-100 messages)
await client.bulkDelete(channelId, messageIds);

// Fetch messages
const messages = await client.fetchMessages(channelId, { limit: 50 });
const single = await client.fetchMessage(channelId, messageId);

// Typing indicator
await client.sendTyping(channelId);

Reactions

// Add / remove reactions
await client.react(channelId, messageId, '👍');
await client.unreact(channelId, messageId, '👍');

// Remove another user's reaction
await client.removeReaction(channelId, messageId, '👍', userId);

// Remove all reactions
await client.removeAllReactions(channelId, messageId);
await client.removeAllReactionsForEmoji(channelId, messageId, '👍');

// Fetch who reacted
const users = await client.fetchReactions(channelId, messageId, '👍');

Pins

await client.pinMessage(channelId, messageId);
await client.unpinMessage(channelId, messageId);
const pins = await client.fetchPinnedMessages(channelId);

Guilds

// Fetch guild info
const guild = await client.fetchGuild(guildId);

// Edit guild
await client.editGuild(guildId, { name: 'New Name' });

// Access cached guilds
for (const [id, guild] of client.guilds) {
  console.log(guild.name);
}

// Audit log
const log = await client.fetchAuditLog(guildId, { limit: 50 });

// Vanity URL
const vanity = await client.fetchVanityUrl(guildId);

Members

// Fetch members
const members = await client.fetchMembers(guildId, { limit: 100 });
const member = await client.fetchMember(guildId, userId);

// Edit member
await client.editMember(guildId, userId, { nick: 'Cool Name' });

// Kick
await client.kickMember(guildId, userId);

// Set bot nickname
await client.setNickname(guildId, 'Bot Name');

Roles

const roles = await client.fetchRoles(guildId);

// Create / edit / delete
const role = await client.createRole(guildId, { name: 'Moderator', color: 0x3498db });
await client.editRole(guildId, roleId, { name: 'Admin' });
await client.deleteRole(guildId, roleId);

// Add / remove from member
await client.addRole(guildId, userId, roleId);
await client.removeRole(guildId, userId, roleId);

Bans

await client.banMember(guildId, userId, { reason: 'Rule violation' });
await client.unbanMember(guildId, userId);
const bans = await client.fetchBans(guildId);

Channels

const channel = await client.fetchChannel(channelId);
const guildChannels = await client.fetchGuildChannels(guildId);

// Create / edit / delete
const ch = await client.createChannel(guildId, { name: 'general', type: 0 });
await client.editChannel(channelId, { topic: 'Updated topic' });
await client.deleteChannel(channelId);

// Permission overwrites
await client.editPermission(channelId, roleId, { type: 0, allow: '1024', deny: '0' });
await client.deletePermission(channelId, roleId);

Emojis & Stickers

const emojis = await client.fetchEmojis(guildId);
const emoji = await client.createEmoji(guildId, { name: 'cool', image: 'data:image/png;base64,...' });
await client.editEmoji(guildId, emojiId, { name: 'cooler' });
await client.deleteEmoji(guildId, emojiId);

const stickers = await client.fetchStickers(guildId);
const sticker = await client.createSticker(guildId, {
  name: 'cool', description: 'A cool sticker', tags: 'cool',
  file: { name: 'sticker.png', data: stickerBuffer },
});
await client.editSticker(guildId, stickerId, { name: 'cooler' });
await client.deleteSticker(guildId, stickerId);

Invites

const invite = await client.createInvite(channelId, { max_age: 86400 });
const channelInvites = await client.fetchChannelInvites(channelId);
const guildInvites = await client.fetchGuildInvites(guildId);
const info = await client.fetchInvite('abc123');
await client.deleteInvite('abc123');

Webhooks

const webhook = await client.createWebhook(channelId, { name: 'My Webhook' });
await client.editWebhook(webhookId, { name: 'Updated' });
await client.executeWebhook(webhookId, token, 'Hello from webhook!');
await client.deleteWebhook(webhookId);

const channelHooks = await client.fetchChannelWebhooks(channelId);
const guildHooks = await client.fetchGuildWebhooks(guildId);

Users

const user = await client.fetchUser(userId);
const dm = await client.createDM(userId);
await client.sendMessage(dm.id, 'Hello!');

Lifecycle

// Connect
await client.login('your-bot-token');

// Leave a guild
await client.leaveGuild(guildId);

// Disconnect
client.destroy();

Events

// Session
client.on('ready', (user, guilds) => { });

// Messages
client.on('messageCreate', (message) => { });
client.on('messageUpdate', (message) => { });
client.on('messageDelete', ({ id, channel_id }) => { });
client.on('messageDeleteBulk', ({ ids, channel_id }) => { });

// Reactions
client.on('messageReactionAdd', (data) => { });
client.on('messageReactionRemove', (data) => { });
client.on('messageReactionRemoveAll', (data) => { });
client.on('messageReactionRemoveEmoji', (data) => { });

// Guilds
client.on('guildCreate', (guild) => { });
client.on('guildUpdate', (guild) => { });
client.on('guildDelete', ({ id }) => { });

// Members
client.on('guildMemberAdd', (member) => { });
client.on('guildMemberUpdate', (member) => { });
client.on('guildMemberRemove', ({ guild_id, user }) => { });

// Roles
client.on('guildRoleCreate', ({ guild_id, role }) => { });
client.on('guildRoleUpdate', ({ guild_id, role }) => { });
client.on('guildRoleDelete', ({ guild_id, role_id }) => { });
client.on('guildRoleUpdateBulk', ({ guild_id, roles }) => { });

// Bans
client.on('guildBanAdd', ({ guild_id, user }) => { });
client.on('guildBanRemove', ({ guild_id, user }) => { });

// Emojis & Stickers
client.on('guildEmojisUpdate', ({ guild_id, emojis }) => { });
client.on('guildStickersUpdate', ({ guild_id, stickers }) => { });

// Channels
client.on('channelCreate', (channel) => { });
client.on('channelUpdate', (channel) => { });
client.on('channelUpdateBulk', (channels) => { });
client.on('channelDelete', (channel) => { });
client.on('channelPinsUpdate', (data) => { });

// Invites
client.on('inviteCreate', ({ code, channel_id }) => { });
client.on('inviteDelete', ({ code, channel_id }) => { });

// Webhooks
client.on('webhooksUpdate', ({ guild_id, channel_id }) => { });

// Voice
client.on('voiceStateUpdate', (state) => { });
client.on('voiceServerUpdate', (data) => { });

// Typing & Presence
client.on('typingStart', (data) => { });
client.on('presenceUpdate', (data) => { });
client.on('userUpdate', (user) => { });

// System
client.on('error', (error) => { });
client.on('debug', (message) => { });

// Raw — any unhandled gateway event
client.on('raw', (event, data) => { });

REST API (Direct)

import { REST, Routes } from 'fluxer.ts';

const rest = new REST({ token: 'your-token' });

// Any endpoint
const user = await rest.get(Routes.currentUser());
const channels = await rest.get(Routes.guildChannels(guildId));

Gateway Intents

import { GatewayIntents, IntentsAll } from 'fluxer.ts';

// Specific intents
const intents = GatewayIntents.Guilds | GatewayIntents.GuildMessages | GatewayIntents.MessageContent;

// All intents
const client = new Client({ intents: IntentsAll });

Type Generation

Types are auto-generated from the Fluxer OpenAPI spec:

node tools/generate-types.mjs > src/types.generated.ts

The generator reads reference/openapi.json and outputs TypeScript interfaces and enums for all bot-relevant API objects. Modify tools/generate-types.mjs to add schemas or change mappings.

Permissions (v0.3.0+)

import { Permissions, hasPermission, combinePermissions } from 'fluxer.ts';

// Check permissions — no more hardcoding bit values
if (hasPermission(member.permissions, Permissions.ManageMessages)) {
  // can delete and pin messages
}

// Administrator bypasses everything automatically
hasPermission(adminPerms, Permissions.SendMessages); // always true

// Combine for role creation
const modPerms = combinePermissions(
  Permissions.KickMembers,
  Permissions.BanMembers,
  Permissions.ManageMessages,
);
await client.createRole(guildId, { name: 'Mod', permissions: modPerms.toString() });

All 35 Fluxer permission values included. See the permissions guide for the full reference.

Examples

Ready-to-run bot examples in examples/:

Documentation

How it differs from @fluxerjs/core

| | fluxer.ts | @fluxerjs/core | |---|---|---| | Size | ~60KB | ~809KB | | Packages | 1 | 7 (monorepo) | | Dependencies | 1 (ws) | 6 | | TypeScript | Source + declarations | Declarations only | | Fluxer-specific | Yes (properties, v1 gateway) | Discord.js port | | API types | Generated from OpenAPI spec | Manual | | Events | 40+ | Unknown | | Client methods | 65 | Unknown |

License

MIT