Skip to main content

puretiktoken

CI PyPI Python tiktoken conformance License: MIT

tiktoken in pure Python: byte-for-byte compatible BPE tokenizer for OpenAI models — no Rust extension, no binary wheel, zero dependencies.

OpenAI's tiktoken is a Rust extension. That's fast, but it means a compiled wheel has to exist (and load) for your platform — which it doesn't on Pyodide/WASM, often fails on fresh ARM or musl/Alpine boxes, bloats AWS Lambda layers, and won't build in locked-down sandboxes with no Rust toolchain. puretiktoken is the same tokenizer written in plain Python, so it runs anywhere Python runs and produces the exact same token ids.

pip install puretiktoken
import puretiktoken as tiktoken      # drop-in: same names, same ids

enc = tiktoken.get_encoding("cl100k_base")
enc.encode("hello world")             # -> [15339, 1917]   (identical to tiktoken)
enc.decode([15339, 1917])             # -> "hello world"

tiktoken.encoding_for_model("gpt-4o").encode("tokens!")   # o200k_base
len(tiktoken.get_encoding("o200k_base").encode(prompt))    # count before an API call

The API mirrors the slice of tiktoken people actually use — get_encoding, encoding_for_model, encode, encode_ordinary, decode, decode_bytes, n_vocab, plus allowed_special / disallowed_special handling — so for token counting and offline tokenization it is a drop-in replacement.

Why pure Python

tiktoken (Rust), Hugging Face tokenizers (Rust) and sentencepiece (C++) are all native extensions — there was no pure-Python tokenizer that matches tiktoken's output. The hard part isn't the BPE merge (that's ~30 lines); it's tiktoken's pre-tokenizer, a fancy-regex pattern using \p{L}/\p{N} Unicode classes, possessive quantifiers and a lookahead — features the stdlib re can't even compile. puretiktoken reproduces that splitter exactly: it translates each character to a single-byte Unicode class code (the only Unicode-aware step, done with str.translate at C speed), then runs an equivalent pattern — now free of \p{...} — in the C re engine, and feeds the pieces to the same rank-based merge. The result is verified byte-for-byte against the real tiktoken (see below).

Zero dependencies, zero binaries: the vocabularies ship gzipped inside the wheel, so it works fully offline — no download of *.tiktoken files at runtime, which is the other thing that breaks tiktoken in sandboxed or air-gapped environments.

Speed, stated honestly

A Rust extension should win — yet on real-world text cl100k_base matches or beats tiktoken here. puretiktoken translates each character to a one-byte Unicode class and lets the C re engine do the splitting, then caches the ids of each pre-token (real text repeats tokens heavily, by Zipf's law) and encodes in one fused pass. It runs at ~4.5–5.7 M tokens/sec on CPython 3.12 — faster than tiktoken on cl100k_base, because it stays in-process while tiktoken pays Python↔Rust overhead on every call.

corpus (CPython 3.12) cl100k_base o200k_base
prose / code / markdown ~0.7–0.9× (beats tiktoken) ~1.3–1.6× tiktoken
adversarial high-entropy¹ ~6× tiktoken ~7× tiktoken

¹ Random unique strings where no token ever repeats, so the cache can't help and it falls back to the pure-Python BPE merge. Real text never looks like this; run python tools/bench.py to measure on your own. (On older CPython the constant factors are higher — e.g. ~1.1×/1.9× on 3.9 — and PyPy JITs it faster still.)

The point was never to beat Rust — it's getting tiktoken's exact ids where tiktoken won't install or run. That it's now also fast on real text is a bonus.

Verified against the real tiktoken

Conformance is differential, the same way purere2 checks itself against the real RE2 and purefzf against the fzf binary: text is tokenized by both puretiktoken and tiktoken and the token ids are compared. Across a curated multilingual/code/emoji corpus plus tens of thousands of randomized inputs over every assigned Unicode codepoint, the output is byte-for-byte identical for both cl100k_base and o200k_base — including the tricky parts: contractions with Unicode case folding ('ſ folds to 's), o200k's camelCase splitting (iPhone → i+Phone), combining marks, and whitespace-run edges. Decoding round-trips losslessly for arbitrary input. The test suite locks this, so any regression fails CI.

The one place puretiktoken and tiktoken can differ is unassigned codepoints. tiktoken's Rust regex bundles its own Unicode database; puretiktoken uses your Python's unicodedata. When those versions disagree about whether a brand-new codepoint is a letter, the split can differ — but only for text that contains codepoints unassigned in your Python, which real-world text never does. The conformance suite asserts this explicitly: every divergence must be explained by an unassigned codepoint; a mismatch on assigned text is treated as a bug.

Encodings

cl100k_base (GPT-4, GPT-3.5, text-embedding-3-*, ada-002) and o200k_base (GPT-4o, GPT-4o-mini, o1, o3). encoding_for_model() maps model names to these, matching tiktoken's mapping for the current model families.

License

MIT. The bundled vocabularies are OpenAI's, distributed under the MIT terms of tiktoken.

Metadata

Release files for puretiktoken 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for puretiktoken 0.2.1
File Size Uploaded Provenance Actions
puretiktoken-0.2.1.tar.gz 2.5 MB With provenance Details for puretiktoken-0.2.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for puretiktoken 0.2.1
File Interpreter ABI Platform Actions
puretiktoken-0.2.1-py3-none-any.whl Python 3 none any Details for puretiktoken-0.2.1-py3-none-any.whl

Total release size: 5.0 MB

Release files / puretiktoken-0.2.1.tar.gz

Download URL puretiktoken-0.2.1.tar.gz
Size 2.5 MB
Tags Source
SHA-256 checksum
How to use checksums
eedb9312635a6502242258832b2a5910f8ade875fe1e61df8ea1ad63d57653e3
BLAKE2b-256 checksum
How to use checksums
fe5e8ddf13ed1695adfe27a6a2fbcecd2569d628ed3fe813227eaa5ff970a4d5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

Release files / puretiktoken-0.2.1-py3-none-any.whl

Download URL puretiktoken-0.2.1-py3-none-any.whl
Size 2.5 MB
Tags Python 3
SHA-256 checksum
How to use checksums
a16635db77deba7382915c78eeb2559a8c0b520876f242cc4b10f501c44c21ca
BLAKE2b-256 checksum
How to use checksums
bbf2f53b04152848fc78b54b2bd5db507a4ef724531b71dd0569091216c4f41a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

Security for puretiktoken 0.2.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for puretiktoken-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page