wcwidth - Simplified wcwidth for MicroPython
January 27, 2026 · View on GitHub
This is a simplified version of wcwidth optimized for MicroPython and embedded systems.
Size Comparison
| Version | Lines of Code | Disk Size | Unicode Versions |
|---|---|---|---|
| MicroPython wcwidth | 746 | 88 KB | 1 version (17.0.0 only) |
| Original wcwidth | 7,888 | 672 KB | 21 versions (4.1.0 - 17.0.0) |
Size reduction: ~90% (from 672 KB to 88 KB)
What's Removed
- Multi-version support (only Unicode 17.0.0 is included)
- Version selection logic and environment variable handling
- Standard library
functools.lru_cache(replaced with simple dict-based cache) - VS15 table (not commonly used)
- Warnings and detailed error messages
- lru_cache replace by simplistic cache implementation
What's Kept
- Full Unicode 17.0.0 character width tables
wcwidth()- character width measurementwcswidth()- string width measurement- Support for:
- Wide characters (CJK, emoji, etc.)
- Zero-width characters (combining marks, ZWJ, etc.)
- VS16 (Variation Selector 16) for emoji modifiers
- Control character detection
Installation
Simplest way to install the module on your MicroPython board is via mpremote mip:
mpremote mip install github:josverl/mp_wcwidth
Usage
from wcwidth import wcwidth, wcswidth
# Get width of a single character
print(wcwidth('A')) # 1 (normal ASCII)
print(wcwidth('你')) # 2 (wide CJK character)
print(wcwidth('🪲')) # 2 (wide emoji)
print(wcwidth('\u0301')) # 0 (combining accent)
print(wcwidth('\n')) # -1 (control character)
# Get width of a string
print(wcswidth('Hello')) # 5
print(wcswidth('你好')) # 4
print(wcswidth('print("🪲")')) # 11
Demo
A simple demo script demo.py is included to showcase the functionality:
# Install the module and demo script to your MicroPython device
mpremote mip install github:josverl/mp_wcwidth
mpremote mip install --target . github:josverl/mp_wcwidth/demo.py
# Run the demo on the device
mpremote exec "exec(open('demo.py').read())"
Caching
The simplified version includes a minimal cache implementation (simple_cache.py) that replaces Python's functools.lru_cache:
- Fixed size: Uses a simple dict with size limit (no reallocation)
- FIFO eviction: When full, clears entire cache (ultra-simple)
- No external dependencies: Pure Python, MicroPython compatible
- Minimal overhead: ~90 lines of code
- Default cache size: 128 entries for
wcwidth()
The cache significantly improves performance for repeated character width lookups.
Testing
All basic functionality works identically to the original:
python -c "import wcwidth; print(wcwidth.wcwidth('🪲'))" # 2
mpremote exec "import wcwidth; print(wcwidth.wcwidth('🪲'))" # 2
License
Same as original wcwidth (MIT License)
Credits
Based on wcwidth by Jeff Quast, which is based on Markus Kuhn's wcwidth.c implementation.