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 🙏

© 2025 – Pkg Stats / Ryan Hefner

vanilla-party

v0.6.2

Published

An easy to use library for simple multi-user JavaScript apps.

Readme

Vanilla Party 🎉

NPM

Vanilla Party is a library for easily prototyping online multi-user apps with JavaScript. Quickly test ideas for multiplayer games, realtime multi-user apps, and multi-computer projects.

Community/Discussions

Contents

Introduction

Features

No Server-Side Code

With Vanilla Party your projects are written using only client-side JavaScript. Quickly try ideas without writing server code or setting up a back-end stack.

Real-time Data Sync

With Vanilla Party you can easily create a shared data object that is automatically synchronized between instances of your project. You can assign and read properties on these objects just like a plain old local javascript object.

Multiple Apps and Rooms

A single Vanilla Party server can support many apps and each app can group users into rooms. Vanilla Party keeps track of which clients are in each room and shares the data to the right clients.

Client-side Hosting

Vanilla Party automatically designates one (and only one) guest in each room as the host. Your code can easily check if it is the host and take care of running the party.

What is it good for?

Prototyping

Vanilla Party provides a simple, imperative interface for working with shared data inspired by the p5.party library. Vanilla Party let's you try ideas quickly without writing server code or setting up a front-end/back-end stack.

Workshops + Classes

Vanilla Party uses a deepstream.io server which is easy to set up and cheap—or free—to run. Many projects can connect to the same Vanilla Party server, so students can focus on coding instead of setting up servers.

What is it not good for?

Production

Vanilla Party is designed for prototypes. As your project grows, you'll need to look into other libraries and backends that suit your project's needs.

Security

Projects built with Vanilla Party are insecure and has no method to authenticate or authorize users. Multiple apps share a server and can read, write, and delete each other's data.

Installation

The quickest way to get started with Vanilla Party is to load or download from a CDN.

Or install via NPM using npm install vanilla-party.

Getting Started

<script src="https://unpkg.com/vanilla-party@latest/dist/vanilla-party.js"></script>
window.addEventListener("load", () => {
  let shared = null
  let div = null

  // server url
  const serverUrl = "wss://vanilla-party.luizbills.com/"

  // your app name (tip: avoid generic names)
  const appName = "my-party-app"

  // the room where users will join
  const room = "main"

  // connect to server
  partyConnect(serverUrl, appName, room)

  // load a shared data object
  partyLoadShared("shared", { x: 0, y: 0 }, (data) => {
    shared = data
    onSharedDataReady()
  })

  // create a div element
  div = document.createElement("div")
  document.body.append(div)
  div.textContent = `connecting...`

  function onSharedDataReady() {
    const size = 64

    div.textContent = ""
    div.style.cssText = `width:${size}px;height:${size}px;background:red;border-radius:100%;position:absolute;`

    window.addEventListener("click", (ev) => {
      // listen clicks and taps and
      // write shared data
      shared.x = ev.clientX - size / 2
      shared.y = ev.clientY - size / 2
    })

    function update() {
      // read shared data
      div.style.left = `${shared.x}px`
      div.style.top = `${shared.y}px`
    }

    // call update() 30 times per second
    setInterval(update, 1000 / 30)
  }
})

Live Demo (Try in two browser windows at once)

Note: This example is using only javascript and HTML to illustrate how easy it is to get started with Vanilla Party. In our examples, we'll use P5.js for user interaction and rendering.

API Documentation

partyConnect(host, appName, roomId?, callback?)

Connects the local user to a Vanilla Party server.

Parameters

host: string

The server to connect to. You can host your own server or use my demo server: wss://vanilla-party.luizbills.com

appName: string

A unique string identifying your app, e.g. luizbills-pong

roomName: string (optional)

A string to namespace users and events within a app. Default: "main"

callback: () => void (optional)

A function to be called when the connection is ready.

Returns

Nothing.


partyDisconnect()

Immediately disconnects the local user. The user’s shared object will be removed from other guests arrays. The disconnect user will have continue to have access to shared objects, including the guest array, but they will no longer sync.

Parameters

None.

Returns

Nothing.


partyLoadShared(name, initObject?, callback?)

Loads or creates a “shared object” with the given name in the current room.

Parameters

name: string

The name of the shared object on the server.

initObject: UserData (optional)

Data to initialize the shared object with, eg. {x: 0, y: 0}.

The shared object is initialized with the values in the data object ONLY if the room is empty when the user connects. If the room already has connected users, then the data object argument will be ignored and loaded from the server.

callback: (data: JSONObject) => void (optional)

A function to be called when the shared object is ready (fully loaded from the server).

Returns

Returns an empty object {} which will be populated with the synced properties as soon as they are loaded from the server. The property values of the shared object are synchronized between connected users in the room.


partyLoadMyShared(initObject?, callback?)

Returns the local user’s shared data object.

Parameters

initObject: UserData (optional)

The data to initialize the shared object with, eg. {favoriteColor: "purple"}.

callback: (data: JSONObject) => void (optional)

A function to be called when the shared object is ready (fully loaded from the server).

Returns

The local user's shared object.


partySetShared(sharedObject, data)

Replaces the current properties of a shared object with the values given in data.

The data is overwritten, not merged. All the existing properties on sharedObject will be removed and the properties in data will replace them.

You can use this function to set all the properties of a shared object at once:

partySetShared(shared, { x: 10, y: 10, z: 10 })

You can use this function to quickly clear or reset a shared object:

partySetShared(shared, {})

Parameters

sharedObject: JSONObject

A shared object.

data: JSONObject

data to write in sharedObject.

Returns

Nothing.


partyLoadGuestShareds()

Vanilla Party maintains a shared object for each user in the room. partyLoadGuestShareds() returns a dynamic array of these shared objects that is kept up to date as users join and leave the room. But if an user’s shared object is empty (it has no properties) it will NOT be included in that dynamic array.

Parameters

None.

Returns

The dynamically updated array of shared objects.


partyWatchShared(shared, [path], callback, triggerNow?)

Watches a shared object and calls the callback when any of its properties change. But you can optionally provide a path on the object to watch.

Parameters

shared: JSONObject

The shared object to watch.

path: string (optional)

A path on the shared object to watch, e.g. "position.x"

callback: (data) => void

A function to call when shared is updated. With path, data will be the new value of the updated property. Without path, data will be the shared.

triggerNow: boolean (optional)

Should the callback fire immediately? Default: false

Returns

Nothing.

Examples

Watch for any changes on shared.

let shared = partyLoadShared("shared")

partyWatchShared(shared, function (sharedUpdated) {
  console.log("received new data on shared:", sharedUpdated)
})

Watch for changes to property x on shared.

let shared = partyLoadShared("shared", { x: 0 })

partyWatchShared(shared, "x", function (x) {
  console.log("x changed to ", x)
})

partyIsHost()

Check to see if the local user has designated as the room’s host.

Vanilla Party designates exactly one user in each occupied room as its host at all times.

Parameters

None.

Returns

Returns true if the local user is the host, otherwise returns false.


partyEmit(eventName, data?)

Broadcast an event message to connected users in this room.

Parameters

eventName: string

The event name.

data: JSONObject (optional)

The data to send.

Returns

Nothing.


partySubscribe(eventName, callback)

Register a callback to handle incoming event messages.

Parameters

eventName: string

The event name to subscribe to.

callback: (data: JSONObject | undefined) => void

A function to be called when event message is received.

Returns

Nothing.


partyUnsubscribe(eventName, callback?)

Stop listening to event messages.

Parameters

eventName: string

The event name to unsubscribe from.

callback: (data: JSONObject | undefined) => void

The callback that you want to remove. If you don’t provide a callback, all callbacks for the provided eventName will be removed.

Returns

Nothing.


partyCountGuests()

Returns the quantity of connected users in the room.

Parameters

None.

Returns

A number.


partyGetRoom()

Returns the Room instance used by the local user connection.

Parameters

Nothing.

Returns

The room instance.


partyToggleInfo(show?)

Use partyToggleInfo() to hide, show, or toggle the visibility of the info panel (useful during development).

The info panel can also be toggled pressing F1 key.

Parameters

show: boolean (optional)

Pass nothing to toggle from the current state. Pass true to show the panel or false to hide the panel.

Returns

Nothing.

Examples

// show the panel at startup.
partyToggleInfo(true)

Frequently Asked Questions

Do I need a username and password to connect to the server?

No.

Can I set up usernames and passwords on my own deepstream.io server?

No. Vanilla Party does not provide any way to limit connections or authenticate users. Adding an authentication and permission system would significantly increase the complexity. Vanilla Party is focused on ease-of-use, experimentation, and prototyping. If you need security, Vanilla Party won’t work for you.

When do I use different app names?

Typically, you use a unique app name for every project you are making.

What would happen if I use the same app name as someone else?

If you use the same app name as someone else on the same server, your shared data and messages might accidentally get mixed up. To avoid using someone else’s app name, add a prefix to your app name. E.g.: instead of "pong", use "johnwick-pong".

What kind of data can be shared?

Shared objects can contain only data. They cannot contain methods or internal (private) state. These simple, data-only objects are sometimes called "Plain Old JavaScript Objects" (POJOs).

Shared objects can share basic data types: numbers, strings, booleans, null, arrays and other objects.

You can not share: Infinity, NaN, functions, DOM Elements, symbol values, class instances, etc.

If you set a property’s value as undefined the property will be removed.

Pro Tip: In general any data that is JSON serializable can be shared, and data that isn’t JSON serializable can not.

How do I avoid data conflicts if I have multiple clients writing to the same object?

If your game requires a shared object across multiple clients, it is pertinent that they write to the object at different times. A few ways to do that are ensuring that only one client (the host) is writing to the object as shown or creating a turn based logic.

How is the host chosen?

When an user connects to an empty room, that user is designated as host immediately and remains host until it disconnects. When the current host disconnects, another host is chosen automatically.

Can I host my own server?

You don’t necessarily need to set up your own server. You can get started with our demo server:

wss://vanilla-party.luizbills.com

This is the easiest way to get started and for quick throw-away prototypes, but don’t count on the server being around for long term. Someday it might move to a new url, have an unplanned outage, or go offline forever. Fortunately, setting up your own server and switching to it isn’t that hard.

But if you need long term stability, you might want to set up your own server using Node.js:

git clone https://github.com/luizbills/deepstream.io-public deepstream-server
cd deepstream-server
npm ci
npm start

Done! Now you have a local deepstream.io server running in your machine on http://localhost:6020.

Alternatively, you can deploy it on a cloud service of your choice (Heroku, Linode, AWS, etc). Even a cheap VPS can support many connections.

Contributing

We welcome new contibuters. Please feel free to start a discussion, report issues, or request features. If you want to help with writing code or documentation, you can start by indicating your interest on an open issue or by creating your own.

Acknowledgements

Vanilla Party is heavily based on jbakse/p5.party, a P5 library builds on deepstream.io and sindresorhus/on-change. Deepstream is a realtime data-sync server that can be easily self hosted on services like Heroku, Digital Ocean, Google Cloud, Fly.io, etc. on-change uses javascript proxies to make a fully observable object.

License

Distributed under the MIT License. See LICENSE for more information.