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

@matrixcoder/axpo

v1.0.4

Published

πŸ’“ A Framework for Acode plugins

Readme

Axpo ⚑

A framework for building Acode plugins with Some features.

Installation

npm install axpo

Quick start & create your first Axpo plugin

npx axpo init

Project Structure

After initialization, your project will have this structure:

my-first-plugin/
β”œβ”€β”€ src/
β”‚   └── main.ts / js         # Your plugin code
β”œβ”€β”€ plugin.json              # Plugin manifest
β”œβ”€β”€ axpo.config.ts / js      # Build configuration
β”œβ”€β”€ tsconfig.json            # TypeScript config
β”œβ”€β”€ package.json             # Dependencies
β”œβ”€β”€ readme.md                # Documentation
β”œβ”€β”€ icon.png                 # Plugin icon (max 50KB)
β”œβ”€β”€ .gitignore               # Git ignore rules
└── build/                   # Build output (auto-generated)

Important Files

| File | Purpose | |------|---------| | src/main.ts/js | Main plugin entry point | | plugin.json | Plugin metadata and configuration | | axpo.config.ts/js | Build and dev server settings | | icon.png | Plugin icon (max 50KB) |


Commands

Inside a plugin project

npm run dev      # Start dev server with hot reload
npm run build    # Build + zip for production
npm run clean    # Clean build output
npm run publish  # Publish to Acode registry

Axpo CLI

axpo init [name]     # Create a new plugin project
axpo dev             # Start development server
axpo build           # Build plugin (creates zip by default)
axpo build --no-zip  # Build only, skip zip
axpo zip             # Create zip from existing build
axpo publish         # Publish plugin to Acode registry
axpo logout          # Clear saved Acode credentials
axpo clean           # Remove build folder and zip files

axpo init options

| Flag | Description | |------|-------------| | [name] | Project folder name | | . | Initialize in current directory | | -y, --yes | Skip prompts, use defaults |

axpo build options

| Flag | Description | |------|-------------| | --no-zip | Skip zip creation | | -o, --output <file> | Custom zip filename | | -w, --watch | Watch mode (same as axpo dev) |

axpo publish options

| Flag | Description | |------|-------------| | -z, --zip <file> | Zip file to publish (default: Plugin.zip) | | -f, --force | Skip confirmation prompt |


Plugin Structure

import { useContext, useSettings } from 'axpo/sdk';

export default function myPlugin() {
  return {
    async init() {
      const { baseUrl, page, pluginId, firstInit } = useContext();
      const settings = useSettings<MySettings>();

      page.setTitle('My Plugin');

      if (firstInit) {
        console.log('First run!');
      }
    },

    async destroy() {
      // cleanup
    },

    settings: [
      {
        key: 'theme',
        text: 'Color Theme',
        type: 'select',
        defaultValue: 'dark',
        options: [['light', 'Light'], ['dark', 'Dark']],
        onChange(value) { applyTheme(value); }
      },
      {
        key: 'fontSize',
        text: 'Font Size',
        type: 'number',
        defaultValue: 14,
        info: 'Size in pixels'
      },
      {
        key: 'enabled',
        text: 'Enable Plugin',
        type: 'checkbox',
        defaultValue: true
      }
    ]
  };
}

Hooks

useContext()

Must be called inside init() or destroy() only.

| Property | Type | Description | |----------|------|-------------| | baseUrl | string | Plugin base URL (with trailing slash) | | page | WCPage | Page/UI manager | | pluginId | string | Unique plugin ID | | firstInit | boolean | First time running? | | cacheFile | File | Cache file object | | cacheFileUrl | string | Cache file URL |

useSettings<T>()

Type-safe settings manager. Pass your settings interface as generic.

| Method | Description | |--------|-------------| | get(key) | Get a single setting value | | getAll() | Get all settings as object | | set(key, value) | Update a setting (triggers onChange) |


Settings Types

| Type | Input | Value | |------|-------|-------| | checkbox | Toggle | boolean | | text | Text field | string | | number | Number field | number | | select | Dropdown | string |

SettingItem Properties

| Property | Type | Required | Description | |----------|------|----------|-------------| | key | string | Yes | Unique identifier for the setting | | text | string | Yes | Display label | | type | SettingType | Yes | Input type (checkbox/text/number/select) | | defaultValue | any | Yes | Default value | | info | string | No | Help text/description | | icon | string | No | Icon name | | iconColor | string | No | Icon color (hex/rgba) | | options | Array | No | Options for select type: [value, label] or value | | placeholder | string | No | Input placeholder | | required | boolean | No | Whether field is required | | match | RegExp | No | Validation regex pattern | | test | Function | No | Custom validation function | | onChange | Function | No | Change event handler |

All setting options:

{
  key: string           // required β€” unique key
  text: string          // required β€” display label
  type: SettingType     // required β€” checkbox | text | number | select
  defaultValue: any     // required β€” default value
  info?: string         // help text
  icon?: string         // icon name
  iconColor?: string    // hex or rgba
  options?: Array<[string, string] | string>  // for select type
  placeholder?: string  // input placeholder
  required?: boolean    
  match?: RegExp        // validation pattern
  test?: (value) => boolean  // custom validation
  onChange?: (value) => void // on change handler
}

Example with type safety:

import { useContext, useSettings } from 'axpo/sdk';
import type { Plugin, SettingItem } from 'axpo/sdk';

interface MySettings {
  theme: 'light' | 'dark';
  fontSize: number;
}

const myPlugin: Plugin = () => {
  return {
    async init() {
      const { page } = useContext();
      const settings = useSettings<MySettings>();

      page.setTitle('My Plugin');
      console.log(settings.get('theme'));
    },

    settings: [
      {
        key: 'theme',
        text: 'Theme',
        type: 'select',
        defaultValue: 'dark',
        options: [['light', 'Light'], ['dark', 'Dark']]
      }
    ] satisfies SettingItem[]
  };
};

export default myPlugin;

Configuration (axpo.config.ts)

import { defineConfig } from 'axpo';

export default defineConfig({
  buildOptions: {
    entryPoints: ['src/main.ts'],
    bundle: true,
    minify: false,
    target: 'es2020',
    alias: { '@': './src' }
  },
  files: ['readme.md', 'icon.png'],
  zipFilename: 'MyPlugin.zip',
  dev: { port: 3000 }
});

plugin.json

{
  "id": "com.example.plugin",
  "name": "Example Plugin",
  "main": "dist/main.js",
  "version": "1.0.0",
  "readme": "readme.md",
  "icon": "icon.png",
  "files": ["worker.js"],
  "minVersionCode": 292,
  "price": 0,
  "license": "MIT",
  "keywords": ["foo","bar"],
  "changelogs": "changelogs.md",
  "author": {
    "name": "Example Author",
    "email": "[email protected]",
    "url": "https://example.com",
    "github": "example"
  }
}

Links