# wa-js: exporting WhatsApp Web's internals as a WPP API

> WPPConnect/WA-JS is an Apache-2.0 licensed TypeScript project that extracts functions from the WhatsApp Web sources and bundles them into a single script you inject into the page, where it exposes a global WPP object with chat, contact, group, blocklist, newsletter and community functions. It suits teams building WhatsApp automation and chat integrations, and it is a poor fit for anything that needs a supported or stable platform contract.

**wppconnect-team/wa-js** — WPPConnect/WA-JS is an open-source project with the aim of exporting functions from WhatsApp Web

- Repository: https://github.com/wppconnect-team/wa-js
- Website: https://wppconnect.io/wa-js/
- Stars: 828 · Forks: 252
- Language: TypeScript
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/wppconnect-team-wa-js

## One injected script and one global object

The project's stated aim is exporting functions from WhatsApp Web, which it describes as an open-source project that can be used to support the creation of any interaction, such as customer service, media sending or intelligence recognition based on phrases.

The mechanism is described in four sentences, and they are the whole architecture.

This project extracts some functions of WhatsApp sources. After build, it generates a file called dist/wppconnect-wa.js to be used for injection in WhatsApp Web. When injected, it exposes a global variable named WPP.

So the pipeline is: take the WhatsApp Web source, extract the internal modules you need, bundle them into one file, inject that file into the running page, and then call the functions from your own code through a global. The parts of the WPP object are organised by role, with WPP.loader holding the scripts that export the WhatsApp functions, WPP.whatsapp holding only the exported WhatsApp functions, and WPP.chat holding chat functions and events.

The audience is teams building WhatsApp automation: customer service tooling, media sending, chat bots, group management, integrations with other systems. The topics attached to the repository list whatsapp-web-automation, whatsapp-bot, whatsapp-integration and whatsapp-api, which is a fair description of the use cases.

The project is Apache-2.0 licensed, the primary language is TypeScript, the homepage is wppconnect.io/wa-js, and the last push to the repository was on 2026-10-19.

## The build produces a single bundle, and the exports map is fixed

The package manifest shows what a consumer actually gets, and it is a bundle rather than a set of modules.

The package name is @wppconnect/wa-js at version 4.7.1, and the exports field points the default entry at dist/wppconnect-wa.js with types at dist/index.d.ts. So the published artifact is the injectable script, and the type definitions are shipped alongside it for the wrapper tooling that calls into it.

The build is webpack, with a development mode that uses an inline source map and a production mode that does not. The prepare script runs husky install, cleans the dist directory and then runs the production build, which means a fresh clone ends up with a built bundle after install.

There is a second half to the repository that the README does not spend much time on: the WhatsApp source itself. The scripts include wa-source:clean, which removes the wa-source directory, and wa-source:format, which runs prettier over it. There are also tools to update model attributes and to update a module id, both run through ts-node.

The reason for keeping a local copy of the WhatsApp source is straightforward. The extraction targets specific internal modules of a specific build of WhatsApp Web, and the module identifiers and their attributes change between WhatsApp releases. Having the source locally and a script to refresh the model attributes is what makes it possible to follow those changes.

That is also the maintenance cost, and it is the single most important thing to understand about the project before adopting it.

## Model, Collection and Store are the naming conventions

Before the function list, the README establishes the conventions, and they are worth learning because every exported object follows them.

A name ending in Model is a class for a data structure, with ClassModel and MsgModel as the examples. A name ending in Collection is a class for a collection of models, such as ChatCollection or MsgCollection. A name ending in Store is the default and global instance of a collection, such as ChatStore or MsgStore.

So the pattern is data structure, container class, and a shared global instance of that container. This is the same shape as an ORM model layer, and it is the shape most of the exported functions operate on. A function that returns a chat is returning something modelled on ChatModel, and a function that lists chats is reading from something like ChatStore.

The practical benefit is that you can navigate the API without the documentation, because the names tell you what you are getting. It also tells you how stable the surface is likely to be. These names are derived from WhatsApp's own internals, and WhatsApp Web is a minified, constantly rebuilt web application, so the underlying identifiers can change shape between versions even when the exported wrapper keeps the same name.

The three layer split of the WPP object, loader, whatsapp and chat, follows the same logic. WPP.loader is the machinery, WPP.whatsapp is the raw exported functions, and WPP.chat is the organised domain layer, with more such as contact, group, blocklist, newsletter and community.

## The function surface is organised by domain

The README lists the available functions by area, and the list reads like an API reference for a WhatsApp client rather than a collection of scripts.

The general functions sit under WPP.conn and cover the session itself: connect to WhatsApp Web, check if the connection is authenticated, log out, get the current WhatsApp build constants, and get stream data for the current stream mode and connection state.

The chat functions sit under WPP.chat and cover messaging: send a text message, send a file message for media such as video, audio, image and PDF, get chat details, and delete a message.

The contact functions under WPP.contact cover the address book: get contact details, get all contacts, get a contact status, get the groups in common with a contact, and get the phone number, lid and contact entry from the local cache.

The group functions under WPP.group are the most detailed block, and they show the level of control the library offers: create a group, check whether a contact can be added, add and remove participants, check whether a contact can be promoted, promote and demote participants, and get group information from an invitation link or invite code, plus a list of all groups.

The blocklist functions cover blocking, unblocking, listing all blocked contacts and checking whether a contact is blocked. The newsletter functions cover WhatsApp Channels, with create, edit, destroy, follow, unfollow, mute, search by name or country, and getting the subscriber list of a newsletter you own. The community functions cover creating a community, deactivating one and adding subgroups.

The range is what makes this useful rather than a toy: a tool that can promote a group participant and read a channel subscriber list is doing administration, not just sending messages.

## The authoritative function list is whatever your browser console prints

The README gives the same instruction after every group of functions, and it is the most useful line in the document for anyone actually working with the library.

For the most up-to-date list of available functions, launch the project locally and run this in your browser console: Object.keys(WPP.conn).sort()

The same pattern is repeated for WPP.chat, WPP.contact, WPP.blocklist, WPP.group, WPP.newsletter and WPP.community.

This tells you something important about how the project treats its own documentation. The README is a curated sample of a surface that changes, and the console is the ground truth. A function that disappeared in the WhatsApp build you are running will not be in the README either, and one that was added last week will not be there yet.

That is why the release numbers move quickly. The recent tags are v4.7.1 on 2026-10-15 and v4.7.0 on 2026-10-14, with the last push to the repository on 2026-10-19. There is also a much older nightly tag from 2021, which looks like a leftover from an earlier release scheme rather than something current.

For a team, the practical consequence is that you pin a version of the package and a version of the WhatsApp Web build together, and you verify the pair rather than trusting the major version alone.

## Webpack, Playwright, release-it and a local WhatsApp Web to test against

The tooling in the package manifest tells you how the project is developed and how you are expected to work with it.

Tests run through Playwright, with npm test running playwright test against the project named tests, and a separate test:prepare project that runs headed. There is a playwright.config.ts in the repository root, and a storageState.json file, which in Playwright is where an authenticated browser session is stored between runs. That combination is the reason the library can be tested against a real WhatsApp Web page rather than a mock.

There are three launch scripts, all run through ts-node: launch:attach, launch:local and launch:protocol-log. The last one captures protocol level traffic, which is what you would reach for when a WhatsApp internal changed and you need to see what the page is now doing.

Releases are handled by release-it, with a .release-it.yml configuration, and the changelog is generated by conventional-changelog using changelog.config.cjs, with scripts to preview the changelog, update it and produce the changelog for the last release. Commits are made with commitizen through the cz script, and husky with lint-staged handles the pre-commit hooks.

Documentation is generated with typedoc, and the API reference is built from the main branch revision. The build:dev mode with an inline source map is what you want while working, and the production build is what ships in the npm package.

The setup is not a one liner, and the reason is inherent to the project. You need a local WhatsApp Web to work against, and the library has to be rebuilt whenever that source changes.

## Conclusion

wa-js suits a team that needs to drive WhatsApp Web programmatically, whether for a customer service bot, a media sending service or a workflow tool, since the WPP object gives you a documented function surface rather than a screen scraping exercise. It does not suit a product that needs a vendor supported interface, because the library tracks the internals of a web application that changes without notice, and the README itself points you at the browser console to discover the current function list. Before you build on it, confirm the WhatsApp terms of service allow the automation you intend, since the Apache 2.0 licence covers the code and not that question, run the build and check the WPP surface against your own WhatsApp Web version, and note that the newest tagged release is v4.7.1 from 2026-10-15 while the last push to the repository was on 2026-10-19.

## FAQ

### What is WPPConnect/WA-JS?

It is an Apache-2.0 licensed open-source project with the aim of exporting functions from WhatsApp Web, so that customer service, media sending, phrase based recognition and other interactions can be built on top. The npm package is @wppconnect/wa-js.

### How does wa-js expose WhatsApp Web functions?

The project extracts functions from the WhatsApp sources and, after build, generates dist/wppconnect-wa.js for injection into WhatsApp Web. When injected it exposes a global variable named WPP, with parts such as WPP.loader, WPP.whatsapp and WPP.chat.

### What do the Model, Collection and Store suffixes mean in wa-js?

A name ending in Model is a class for a data structure such as ClassModel or MsgModel, a name ending in Collection is a class for a collection of models such as ChatCollection, and a name ending in Store is the default and global instance of such a collection such as ChatStore.

### How do I find the current list of functions in wa-js?

The README says to launch the project locally and run the relevant Object.keys call in your browser console, for example Object.keys(WPP.conn).sort(), and repeats the instruction for the chat, contact, blocklist, group, newsletter and community namespaces.

### How is wa-js tested and released?

The package manifest shows tests running through Playwright, with a playwright.config.ts and a storageState.json in the repository, a webpack build, husky and lint-staged for pre-commit checks, release-it for releases and conventional-changelog with commitizen for the changelog and commit format.

## Sources

- [License: Apache-2.0](https://github.com/wppconnect-team/wa-js/blob/main/LICENSE)
- [Project website](https://wppconnect.io/wa-js/)
- [README](https://github.com/wppconnect-team/wa-js/blob/main/README.md)
- [Releases](https://github.com/wppconnect-team/wa-js/releases)
- [wppconnect-team/wa-js on GitHub](https://github.com/wppconnect-team/wa-js)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wppconnect-team-wa-js
