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
- Live site:
jonesum.wtf - Webapp repo:
emboiko/alex_jonesum_app
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).
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))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))- 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.
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.json
makeThis produces libjonesum.a (useful for validating the C compilation independently).
To clean build artifacts:
make cleancd 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))"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));"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.
When someone runs pip install alex-jonesum, there are two scenarios:
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)
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 wheelsnpm 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.
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.
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.
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
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.
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.
Tip: PyPI does not allow re-uploading the same filename. If python/dist/ contains older builds,
either delete them first or upload only the current versionβs files.
- Node:
node/package.jsonversion - Python:
python/pyproject.tomlproject.version - Python:
python/setup.pyversion
cd node
npm publishcd python
Remove-Item -Recurse -Force dist, build, *.egg-info -ErrorAction SilentlyContinue
python -m build
python -m twine upload dist/alex_jonesum-<VERSION>*Tag in git after publishing (example):
git tag v2.0.1
git push --tags