alex-jonesum
v2.0.3
Published
Alex Jones Ipsum generator with C core and Node.js bindings
Maintainers
Readme
Alex Jonesum
A meme lorem-ipsum generator that produces “Alex Jones Ipsum”.
This repo is intentionally a bindings demo:
- C core: the actual generator logic lives in
src/jonesum.c - Python bindings: a Python C-extension in
python/alex_jonesum/_jonesum.c - Node.js bindings: an N-API addon in
node/src/addon.cc
Web app
- Live site:
jonesum.wtf - Webapp repo:
emboiko/alex_jonesum_app
API
The public API is intentionally small: you call rant().
Internally, rant() concatenates multiple sentences produced by Alex's internal process of pontification.
- In C,
jonesum_rant()callsjonesum_pontificate()repeatedly. - In Python and Node.js, only
rant()is exposed (no publicpontificate()method).
Python
Install (normal users):
pip install alex-jonesumInstall (from this repo):
cd python
pip install .Use:
from alex_jonesum import AlexJones
alex = AlexJones()
print(alex.rant())
print(alex.rant(6))Node.js
Install (normal users):
npm install alex-jonesumInstall (from this repo):
cd node
npm installUse:
const AlexJones = require("alex-jonesum")
const alex = new AlexJones()
console.log(alex.rant())
console.log(alex.rant(6))Vocabulary
- Source of truth:
src/vocabulary.txt - Packaging:
- Python copies it into
python/alex_jonesum/vocabulary.txtduring build (overwrites) - Node copies it into
node/vocabulary.txtduringnpm install/npm pack(overwrites)
- Python copies it into
To extend vocabulary, just append new lines to src/vocabulary.txt.
Repo layout
alex_jonesum/
├── src/ # C core + vocabulary
│ ├── jonesum.c
│ ├── jonesum.h
│ └── vocabulary.txt
├── python/ # Python package (pip)
│ ├── alex_jonesum/
│ ├── pyproject.toml
│ └── setup.py
├── node/ # Node package (npm)
│ ├── src/
│ ├── binding.gyp
│ └── package.jsonBuilding (developers)
C core (standalone)
makeThis produces libjonesum.a (useful for validating the C compilation independently).
To clean build artifacts:
make cleanPython (editable install)
cd python
pip install -e .This installs the package in "editable" mode, so changes to Python code take effect immediately. The C extension is compiled during installation.
You need Python development headers available (on Windows this usually means installing Python from python.org and building with MSVC).
Testing the Python package:
cd python
python -c "from alex_jonesum import AlexJones; alex = AlexJones(); print(alex.rant(3))"Node.js
cd node
npm installThis uses node-gyp to compile the native addon. On Windows you'll typically need:
- Visual Studio Build Tools (C++ workload)
- a supported Python for node-gyp
Windows troubleshooting:
Visual Studio 2026 (Build Tools 18) is not yet supported by node-gyp v11.2.0. If you're using VS 2026, you have two options:
Install VS 2022 Build Tools alongside 2026 (recommended):
- Install "Desktop development with C++" workload from VS 2022 Build Tools
node-gypwill automatically detect and use VS 2022
Wait for
node-gypto add support for VS 2026, or use an older Node.js version that might work with different build tools.
Testing the Node.js package:
cd node
npm testOr manually:
cd node
node -e "const AlexJones=require('./src/jonesum'); const alex=new AlexJones(); console.log(alex.rant(3));"How compilation works for end users
npm packages (Node.js)
When someone runs npm install alex-jonesum:
- npm downloads the package from the registry (includes source code in the tarball)
- npm runs the
installscript (defined inpackage.json):node-gyp rebuild, which:- Reads
binding.gypto understand what to compile - Compiles
src/addon.cc(C++) andsrc/jonesum.c(C) into a native addon - Produces
build/Release/jonesum.node(orbuild/Debug/jonesum.nodein debug mode)
- Reads
- The compiled
.nodefile is platform-specific (Windows.node, Linux.node, macOS.node)
Key point: npm packages with native modules compile on the user's machine during installation. The source code is included in the npm package, and users need build tools installed.
pip packages (Python)
When someone runs pip install alex-jonesum, there are two scenarios:
Source distribution (sdist)
If you publish only a source distribution:
- pip downloads the
.tar.gzfrom PyPI - pip extracts and runs
setup.py, which:- Compiles the C extension (
_jonesum.c+jonesum.c) using the user's compiler - Copies
vocabulary.txtinto the package - Installs the compiled extension
- Compiles the C extension (
- Users need build tools (MSVC on Windows, GCC/clang on Linux/macOS)
Wheel (pre-compiled)
If you publish wheels (.whl files):
- pip downloads the pre-compiled wheel for the user's platform
- No compilation happens — the C extension is already compiled
- Users don't need build tools — installation is much faster
Best practice: Publish both source distributions (for compatibility) and wheels (for convenience). You can build wheels with:
cd python
python -m build # Creates both sdist and wheelsWhat gets included in packages?
npm package (node/package.json files field):
src/(JavaScript + native source code)vocabulary.txt(copied duringprepack)README.md(copied duringprepack)binding.gyp(build configuration)- Not included:
node_modules/,build/(compiled artifacts)
Why does Node use both prepare and prepack?
prepackruns right beforenpm pack/npm publish. We use it to copy repo assets (C core source/header,vocabulary.txt, andREADME.md) into the package so the published tarball is self-contained and npm can render the README.prepareruns when installing from a git URL and in some local/dev flows. It points to the same script so the package is usable without requiring a separate manual “copy assets” step during development.
Python package (python/setup.py + MANIFEST.in):
- Source code (
.py,.cfiles) vocabulary.txt(copied during build)- Not included:
build/,dist/,*.egg-info/(build artifacts)
The C core source (src/jonesum.c, src/jonesum.h) is included in both packages because it needs to be compiled as part of the native module.
Windows toolchains (why MSVC?)
Node.js native addons
On Windows, node-gyp expects MSVC (Visual Studio Build Tools). While it’s possible to use MinGW in some setups, it’s not the canonical path and is a common source of “it builds on my machine” problems.
Python C extensions
On Windows, Python extensions are typically built with MSVC to match the toolchain used to build CPython. If you want to publish wheels, MSVC is the standard approach.
“Why do we cd node to build?” (monorepo dev vs real usage)
This repo contains two packages (one under python/, one under node/). When you run:
cd node && npm install
you are building this package locally (and compiling the native addon). You are not “installing the package into itself as a dependency”.
When you actually use the package in another project, you would either:
- Install from npm:
npm install alex-jonesum
- Or for local testing from this repo:
npm install /path/to/this/repo/node
Same idea for Python:
- Installing from PyPI:
pip install alex-jonesum
- Or local testing from this repo:
pip install /path/to/this/repo/python
Extending the project (beyond vocabulary)
You’ll typically make changes in this order:
- Update the C core in
src/jonesum.c/src/jonesum.h - Expose new core functions to Python in
python/alex_jonesum/_jonesum.c - Expose new core functions to Node in
node/src/addon.cc - Decide the public API in:
- Python:
python/alex_jonesum/__init__.py - Node:
node/src/jonesum.js
- Python:
The wrappers often look “similar” because they both do the same job: convert native language types to/from the C API and manage memory.
Releasing (manual process)
This repo is a monorepo, but npm and PyPI releases are separate. Keep versions in sync manually for now.
Versioning policy: we keep Node and Python versions in lockstep (same version number), even if a given patch only changes one side. This avoids confusion and makes it easy to know which releases correspond across registries.
1) Update versions (must match)
- Node:
node/package.jsonversion - Python:
python/pyproject.tomlproject.version - Python:
python/setup.pyversion
2) Publish to npm
cd node
npm publish3) Publish to PyPI
cd python
python -m build
python -m twine upload dist/*4) Tag the release (recommended)
Tag in git after publishing (example):
git tag v2.0.1
git push --tags