{"id":13434724,"url":"https://github.com/ada-url/ada","last_synced_at":"2026-01-08T17:08:38.741Z","repository":{"id":64918841,"uuid":"579485798","full_name":"ada-url/ada","owner":"ada-url","description":"WHATWG-compliant and fast URL parser written in modern C++, part of Node.js, Clickhouse, Redpanda, Kong, Telegram, Datadog and Cloudflare Workers.","archived":false,"fork":false,"pushed_at":"2025-05-03T00:07:20.000Z","size":26031,"stargazers_count":1528,"open_issues_count":23,"forks_count":101,"subscribers_count":24,"default_branch":"main","last_synced_at":"2025-05-07T21:09:10.799Z","etag":null,"topics":["cpp","neon","parser","performance","simd","sse2","url","whatwg-url"],"latest_commit_sha":null,"homepage":"https://ada-url.com","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ada-url.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["anonrig","lemire"]}},"created_at":"2022-12-17T21:13:37.000Z","updated_at":"2025-05-06T19:50:10.000Z","dependencies_parsed_at":"2024-01-21T18:25:15.451Z","dependency_job_id":"1bf4bedc-34e3-429d-939e-ab9888beb0be","html_url":"https://github.com/ada-url/ada","commit_stats":{"total_commits":1094,"total_committers":40,"mean_commits":27.35,"dds":"0.46709323583180984","last_synced_commit":"f3da8372114e2ff53279a20fc17c084403ba2b38"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ada-url%2Fada","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ada-url%2Fada/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ada-url%2Fada/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ada-url%2Fada/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ada-url","download_url":"https://codeload.github.com/ada-url/ada/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254059511,"owners_count":22007769,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","neon","parser","performance","simd","sse2","url","whatwg-url"],"created_at":"2024-07-31T03:00:21.491Z","updated_at":"2026-01-08T17:08:38.735Z","avatar_url":"https://github.com/ada-url.png","language":"C++","readme":"# Ada\n[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ada-url/ada/badge)](https://securityscorecards.dev/viewer/?uri=github.com/ada-url/ada)\n[![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7085/badge)](https://bestpractices.coreinfrastructure.org/projects/7085)\n[![Ubuntu 22.04](https://github.com/ada-url/ada/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/ada-url/ada/actions/workflows/ubuntu.yml)\n[![VS17-CI](https://github.com/ada-url/ada/actions/workflows/visual_studio.yml/badge.svg)](https://github.com/ada-url/ada/actions/workflows/visual_studio.yml)\n[![VS17-clang-CI](https://github.com/ada-url/ada/actions/workflows/visual_studio_clang.yml/badge.svg)](https://github.com/ada-url/ada/actions/workflows/visual_studio_clang.yml)\n[![Ubuntu s390x (GCC 11)](https://github.com/ada-url/ada/actions/workflows/ubuntu-s390x.yml/badge.svg)](https://github.com/ada-url/ada/actions/workflows/ubuntu-s390x.yml)\n\nAda is a fast and spec-compliant URL parser written in C++.\nSpecification for URL parser can be found from the\n[WHATWG](https://url.spec.whatwg.org/#url-parsing) website.\n\nAda library also includes a [URLPattern](https://url.spec.whatwg.org/#urlpattern) implementation\nthat is compatible with the [web-platform tests](https://github.com/web-platform-tests/wpt/tree/master/urlpattern).\n\nThe Ada library passes the full range of tests from the specification,\nacross a wide range of platforms (e.g., Windows, Linux, macOS). It fully\nsupports the relevant [Unicode Technical Standard](https://www.unicode.org/reports/tr46/#ToUnicode).\n\nA common use of a URL parser is to take a URL string and normalize it.\nThe WHATWG URL specification has been adopted by most browsers.  Other tools, such as curl and many\nstandard libraries, follow the RFC 3986. The following table illustrates possible differences in practice\n(encoding of the host, encoding of the path):\n\n| string source           | string value                                                |\n|:------------------------|:------------------------------------------------------------|\n| input string            | https://www.7‑Eleven.com/Home/Privacy/Montréal              |\n| ada's normalized string | https://www.xn--7eleven-506c.com/Home/Privacy/Montr%C3%A9al |\n| curl 7.87               | (returns the original unchanged)                            |\n\n## Ada is fast.\n\nOn a benchmark where we need to validate and normalize [thousands URLs found\non popular websites](https://github.com/ada-url/url-various-datasets/tree/main/top100),\nwe find that ada can be several times faster than popular competitors (system: Apple MacBook 2022\nwith LLVM 14).\n\n\n```\n      ada ▏  188 ns/URL ███▏\nservo url ▏  664 ns/URL ███████████▎\n     CURL ▏ 1471 ns/URL █████████████████████████\n```\n\nAda has improved the performance of the popular JavaScript environment Node.js:\n\n\u003e Since Node.js 18, a new URL parser dependency was added to Node.js — Ada. This addition bumped the Node.js performance when parsing URLs to a new level. Some results could reach up to an improvement of **400%**. ([State of Node.js Performance 2023](https://blog.rafaelgss.dev/state-of-nodejs-performance-2023))\n\nThe Ada library is used by important systems besides Node.js such as Redpanda, Kong, Telegram, DataDog, and Cloudflare Workers.\n\n[![the ada library](http://img.youtube.com/vi/tQ-6OWRDsZg/0.jpg)](https://www.youtube.com/watch?v=tQ-6OWRDsZg)\u003cbr /\u003e\n\n### Requirements\n\nThe project is otherwise self-contained and it has no dependency.\nA recent C++ compiler supporting C++20. We test GCC 12 or better, LLVM 14 or better and Microsoft Visual Studio 2022.\n\n## Installation\n\nBinary packages for the following systems are currently available:\n\n[![Packaging status](https://repology.org/badge/vertical-allrepos/ada.svg)](https://repology.org/project/ada/versions)\n\n## Quick Start\n\nLinux or macOS users might follow the following instructions if they have a recent C++ compiler installed and a standard utility (`wget`)\n\n\n1. Pull the library in a directory\n   ```\n   wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.cpp\n   wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.h\n   ```\n2. Create a new file named `demo.cpp` with this content:\n   ```C++\n    #include \"ada.cpp\"\n    #include \"ada.h\"\n    #include \u003ciostream\u003e\n\n    int main(int, char *[]) {\n      auto url = ada::parse(\"https://www.google.com\");\n      if (!url) {\n        std::cout \u003c\u003c \"failure\" \u003c\u003c std::endl;\n        return EXIT_FAILURE;\n      }\n      url-\u003eset_protocol(\"http\");\n      std::cout \u003c\u003c url-\u003eget_protocol() \u003c\u003c std::endl;\n      std::cout \u003c\u003c url-\u003eget_host() \u003c\u003c std::endl;\n      return EXIT_SUCCESS;\n    }\n   ```\n3. Compile\n   ```\n   c++ -std=c++20 -o demo demo.cpp\n   ```\n4. `./demo`\n\n   ```\n   http:\n   www.google.com\n   ```\n\n## Bindings of Ada\n\nThe following libraries are maintained by the Ada team and available under [Ada GitHub organization](https://github.com/ada-url).\n\n- [Rust](https://github.com/ada-url/rust): Rust bindings for Ada\n- [Go](https://github.com/ada-url/goada): Go bindings for Ada\n- [Python](https://github.com/ada-url/python): Python bindings for Ada\n\n### Community maintained\n\n- [R](https://github.com/schochastics/adaR): R wrapper for Ada\n- [PHP](https://github.com/lnear-dev/ada-url): PHP Wrapper for Ada URL\n- [LuaJIT](https://github.com/bungle/lua-resty-ada): LuaJIT FFI bindings for Ada\n- [Zig](https://github.com/braheezy/ada-zig): Unofficial Zig bindings for Ada\n- [Python](https://github.com/TkTech/can_ada): Python bindings for Ada\n- [React Native](https://github.com/KusStar/react-native-fast-url): A Fast URL and URLSearchParams polyfill for React Native.\n- [D](https://github.com/kassane/ada-d): D bindings for Ada, `@nogc`, `nothrow` and `@safe` compat.\n- [Nim](https://github.com/ferus-web/nim-ada): High-level Nim abstraction over Ada, uses ORC move semantics to safely and efficiently handle memory.\n\n## Usage\n\nAda supports two types of URL instances, `ada::url` and `ada::url_aggregator`. The usage is\nthe same in either case: we have an parsing function template `ada::parse` which can return\neither a result of type `ada::result\u003cada::url\u003e` or of type `ada::result\u003cada::url_aggregator\u003e`\ndepending on your needs. The `ada::url_aggregator` class is smaller and it is backed by a precomputed\nserialized URL string. The `ada::url` class is made of several separate strings for the various\ncomponents (path, host, and so forth).\n\n### Parsing \u0026 Validation\n\n- Parse and validate a URL from an ASCII or a valid UTF-8 string.\n\n```cpp\nauto url = ada::parse\u003cada::url_aggregator\u003e(\"https://www.google.com\");\nif (url) { /* URL is valid */ }\n```\n\nAfter calling 'parse', you *must* check that the result is valid before\naccessing it when you are not sure that it will succeed. The following\ncode is unsafe:\n\n```cpp\nauto\u003e url = ada::parse\u003cada::url_aggregator\u003e(\"some bad url\");\nurl-\u003eget_href();\n```\n\nFor simplicity, in the examples below, we skip the check because\nwe know that parsing succeeds. All strings are assumed to be valid\nUTF-8 strings.\n\n## Examples\n\n## URL Parser\n\n```c++\nauto url = ada::parse\u003cada::url_aggregator\u003e(\"https://www.google.com\");\n\nurl-\u003eset_username(\"username\"); // Update credentials\nurl-\u003eset_password(\"password\");\n// ada-\u003eget_href() will return \"https://username:password@www.google.com/\"\n\nurl-\u003eset_protocol(\"wss\"); // Update protocol\n// url-\u003eget_protocol() will return \"wss:\"\n\nurl-\u003eset_host(\"github.com\"); // Update host\n// url-\u003eget_host() will return \"github.com\"\n\nurl-\u003eset_port(\"8080\"); // Update port\n// url-\u003eget_port() will return \"8080\"\n\nurl-\u003eset_pathname(\"/my-super-long-path\"); // Update pathname\n// url-\u003eget_pathname() will return \"/my-super-long-path\"\n\nurl-\u003eset_search(\"target=self\"); // Update search\n// url-\u003eget_search() will return \"?target=self\"\n\nurl-\u003eset_hash(\"is-this-the-real-life\"); // Update hash/fragment\n// url-\u003eget_hash() will return \"#is-this-the-real-life\"\n```\n\n### URL Search Params\n\n```cpp\nada::url_search_params search_params(\"a=b\u0026c=d\u0026e=f\");\nsearch_params.append(\"g=h\");\n\nsearch_params.get(\"g\");  // will return \"h\"\n\nauto keys = search_params.get_keys();\nwhile (keys.has_next()) {\n  auto key = keys.next();  // \"a\", \"c\", \"e\", \"g\"\n}\n```\n\n### URLPattern\n\nOur implementation doesn't provide a regex engine and leaves the decision of choosing the right engine to the user.\nThis is done as a security measure since the default std::regex engine is not safe and open to DDOS attacks.\nRuntimes like Node.js and Cloudflare Workers use the V8 regex engine, which is safe and performant.\n\n```cpp\n// Define a regex engine that conforms to the following interface\n// For example we will use v8 regex engine\n\nclass v8_regex_provider {\n public:\n  v8_regex_provider() = default;\n  using regex_type = v8::Global\u003cv8::RegExp\u003e;\n  static std::optional\u003cregex_type\u003e create_instance(std::string_view pattern,\n                                                   bool ignore_case);\n  static std::optional\u003cstd::vector\u003cstd::optional\u003cstd::string\u003e\u003e\u003e regex_search(\n      std::string_view input, const regex_type\u0026 pattern);\n  static bool regex_match(std::string_view input, const regex_type\u0026 pattern);\n};\n\n// Define a URLPattern\nauto pattern = ada::parse_url_pattern\u003cv8_regex_provider\u003e(\"/books/:id(\\\\d+)\", \"https://example.com\");\n\n// Check validity\nif (!pattern) { return EXIT_FAILURE; }\n\n// Match a URL\nauto match = pattern-\u003ematch(\"https://example.com/books/123\");\n\n// Test a URL\nauto matched = pattern-\u003etest(\"https://example.com/books/123\");\n```\n\n### C wrapper\n\nSee the file `include/ada_c.h` for our C interface. We expect ASCII or UTF-8 strings.\n\n```C\n#include \"ada_c.h\"\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstdbool.h\u003e\n#include \u003cstring.h\u003e\n\nstatic void ada_print(ada_string string) {\n  printf(\"%.*s\\n\", (int)string.length, string.data);\n}\n\nint main(int c, char *arg[] ) {\n  const char* input =\n      \"https://username:password@www.google.com:8080/\"\n      \"pathname?query=true#hash-exists\";\n  ada_url url = ada_parse(input, strlen(input));\n  if(!ada_is_valid(url)) { puts(\"failure\"); return EXIT_FAILURE; }\n  ada_print(ada_get_href(url)); // prints https://username:password@host:8080/pathname?query=true#hash-exists\n  ada_print(ada_get_protocol(url)); // prints https:\n  ada_print(ada_get_username(url)); // prints username\n  ada_set_href(url, \"https://www.yagiz.co\", strlen(\"https://www.yagiz.co\"));  \n  if(!ada_is_valid(url)) { puts(\"failure\"); return EXIT_FAILURE; }\n  ada_set_hash(url, \"new-hash\", strlen(\"new-hash\"));\n  ada_set_hostname(url, \"new-host\", strlen(\"new-host\"));\n  ada_set_host(url, \"changed-host:9090\", strlen(\"changed-host:9090\"));\n  ada_set_pathname(url, \"new-pathname\", strlen(\"new-pathname\"));\n  ada_set_search(url, \"new-search\", strlen(\"new-search\"));\n  ada_set_protocol(url, \"wss\", 3);  \n  ada_print(ada_get_href(url)); // will print wss://changed-host:9090/new-pathname?new-search#new-hash\n\n  // Manipulating search params\n  ada_string search = ada_get_search(url);\n  ada_url_search_params search_params =\n      ada_parse_search_params(search.data, search.length);\n  ada_search_params_append(search_params, \"a\", 1, \"b\", 1);\n  ada_owned_string result = ada_search_params_to_string(search_params);\n  ada_set_search(url, result.data, result.length);\n  ada_free_owned_string(result);\n  ada_free_search_params(search_params);\n\n  ada_free(url);\n  return EXIT_SUCCESS;\n}\n```\n\nWhen linking against the ada library from C++, be minding that ada requires access to the standard\nC++ library. E.g., you may link with the C++ compiler.\n\nE.g., if you grab our single-header C++ files (`ada.cpp` and `ada.h`), as well as the C header (`ada_c.h`),\nyou can often compile a C program (`demo.c`) as follows under Linux/macOS systems:\n\n```\nc++ -c ada.cpp -std=c++20\ncc -c demo.c\nc++ demo.o ada.o -o cdemo\n./cdemo\n```\n\n### Command-line interface\n\nFor more information about command-line options, please refer to the [CLI documentation](docs/cli.md).\n\n### CMake dependency\n\nSee the file `tests/installation/CMakeLists.txt` for an example of how you might use ada from your own\nCMake project, after having installed ada on your system.\n\n## Contributing\n\n### Building\n\nAda uses cmake as a build system, but also supports Bazel. It's recommended you to run the following \ncommands to build it locally.\n\nWithout tests:\n\n- **Build**: `cmake -B build \u0026\u0026 cmake --build build`\n\nWith tests (requires git):\n\n- **Build**: `cmake -B build -DADA_TESTING=ON \u0026\u0026 cmake --build build`\n- **Test**: `ctest --output-on-failure --test-dir build`\n\nWith tests (requires available local packages):\n\n- **Build**: `cmake -B build -DADA_TESTING=ON -D CPM_USE_LOCAL_PACKAGES=ON \u0026\u0026 cmake --build build`\n- **Test**: `ctest --output-on-failure --test-dir build`\n\n### Build options\n\nAda provides several CMake options to customize the build:\n\n- `ADA_USE_SIMDUTF`: Enables SIMD-accelerated Unicode processing via simdutf (default: OFF)\n\nWindows users need additional flags to specify the build configuration, e.g. `--config Release`.\n\nThe project can also be built via docker using default docker file of repository with following commands.\n\n`docker build -t ada-builder . \u0026\u0026 docker run --rm -it -v ${PWD}:/repo ada-builder`\n\n### Amalgamation\n\nYou may amalgamate all source files into only two files (`ada.h` and `ada.cpp`) by typing executing the Python\n3 script `singleheader/amalgamate.py`. By default, the files are created in the `singleheader` directory.\n\n### License\n\nThis code is made available under the Apache License 2.0 as well as the MIT license.\n\nOur tests include third-party code and data. The benchmarking code includes third-party code: it is provided for research purposes only and not part of the library.\n\n\n### Further reading\n\n* Yagiz Nizipli, Daniel Lemire, [Parsing Millions of URLs per Second](https://doi.org/10.1002/spe.3296), Software: Practice and Experience 54(5) May 2024.\n\n## Stars\n\n\n[![Star History Chart](https://api.star-history.com/svg?repos=ada-url/ada\u0026type=Date)](https://www.star-history.com/#ada-url/ada\u0026Date)\n","funding_links":["https://github.com/sponsors/anonrig","https://github.com/sponsors/lemire"],"categories":["Networking","C++","HarmonyOS","performance","Parsing","Language bindings"],"sub_categories":["Windows Manager","C/C++"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fada-url%2Fada","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fada-url%2Fada","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fada-url%2Fada/lists"}