A pure Dart implementation of Punycode (RFC 3492) with support for mixed-case annotation and technical errata.
Punycoder provides an idiomatic and high-performance way to encode and decode Punycode strings, which are essential for Internationalized Domain Names in Applications (IDNA).
- Standard Compliant: Faithful implementation of the Bootstring algorithm specifically for Punycode.
- Mixed-Case Annotation: Full support for Appendix A, preserving original character casing during the encoding process.
- Cross-Platform: Fully compatible with both the Dart VM and Web (transpiled via dart2js or ddc).
- Native Performance: Uses
StringBufferand Unicode-awareRunesfor efficient processing. - Idiomatic API: Implements
Codec<String, String>for seamless integration withdart:convert.
Add punycoder to your pubspec.yaml dependencies:
dependencies:
punycoder: ^0.3.0Then, import the library in your Dart code:
import 'package:punycoder/punycoder.dart';// Encode a Unicode string to Punycode
final encoded = punycode.encode('münchen'); // mnchen-3ya
// Decode a Punycode string back to Unicode
final decoded = punycode.decode('mnchen-3ya'); // münchenPunycoder provides high-level helpers for handling Internationalized Domain Names (IDN) and email addresses.
// Convert a Unicode domain to ASCII (Punycode)
final domainAscii = domainToAscii('mañana.com'); // xn--maana-pta.com
// Convert back to Unicode
final domainUnicode = domainToUnicode('xn--maana-pta.com'); // mañana.com
// Supports IDNA2003 separators (。 . 。)
final alternative = domainToAscii('mañana\u3002com'); // xn--maana-pta.com
// Convert an email address
final emailAscii = emailToAscii('джумла@джpумлатест.bрфa');
// джумла@xn--p-8sbkgc5ag7bhce.xn--ba-lmcqBy default, domainToAscii and emailToAscii perform validation (label length, domain length, invalid characters). You can disable this if needed:
final raw = domainToAscii('ab--c.com', validate: false);By default, Punycoder uses Appendix A annotations to preserve casing:
final encoded = punycode.encode('MÜnchen'); // Mnchen-3yA
final decoded = punycode.decode('Mnchen-3yA'); // MÜnchenContributions are welcome! Please feel free to open issues or submit pull requests on the GitHub repository.
If you encounter any bugs or have feature requests, please file them through the issue tracker.
This project is licensed under the MIT License - see the LICENSE file for details.