{"id":47305654,"url":"https://github.com/twocaretcat/tally-ts","last_synced_at":"2026-03-17T07:59:23.229Z","repository":{"id":321524255,"uuid":"1085446797","full_name":"twocaretcat/tally-ts","owner":"twocaretcat","description":"A TypeScript word counting library. Count the number of characters, words, sentences, paragraphs, and lines in your text instantly with tally-ts","archived":false,"fork":false,"pushed_at":"2026-02-24T03:03:31.000Z","size":178,"stargazers_count":1,"open_issues_count":15,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-24T09:34:14.626Z","etag":null,"topics":["character-counter","library","line-counter","paragraph-counter","sentence-counter","text-analysis","text-analyzer","text-statistics","typescript","word-counter"],"latest_commit_sha":null,"homepage":"https://johng.io/p/tally-ts","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twocaretcat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"jerboa88","patreon":"jerboa88"}},"created_at":"2025-10-29T03:49:34.000Z","updated_at":"2026-02-24T03:03:34.000Z","dependencies_parsed_at":"2025-10-30T05:43:05.391Z","dependency_job_id":null,"html_url":"https://github.com/twocaretcat/tally-ts","commit_stats":null,"previous_names":["jerboa88/tally-ts","twocaretcat/tally-ts"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/twocaretcat/tally-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twocaretcat%2Ftally-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twocaretcat%2Ftally-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twocaretcat%2Ftally-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twocaretcat%2Ftally-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twocaretcat","download_url":"https://codeload.github.com/twocaretcat/tally-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twocaretcat%2Ftally-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30617990,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T04:46:40.957Z","status":"ssl_error","status_checked_at":"2026-03-17T04:46:32.538Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["character-counter","library","line-counter","paragraph-counter","sentence-counter","text-analysis","text-analyzer","text-statistics","typescript","word-counter"],"created_at":"2026-03-17T07:59:22.739Z","updated_at":"2026-03-17T07:59:23.217Z","avatar_url":"https://github.com/twocaretcat.png","language":"TypeScript","funding_links":["https://github.com/sponsors/jerboa88","https://patreon.com/jerboa88"],"categories":[],"sub_categories":[],"readme":"\u003c!-- Project Header --\u003e\n\u003cdiv align=\"center\"\u003e\n\t\u003ch1 class=\"projectName\"\u003e\n\t\t\u003cpicture\u003e\n\t\t\t\u003csource media=\"(prefers-color-scheme: light)\" srcset=\"docs/logo-light.svg\"\u003e\n\t\t\t\u003cimg class=\"projectLogo\" src=\"docs/logo.svg\" alt=\"Project logo\" title=\"Project logo\" width=\"256\"\u003e\n\t\t\u003c/picture\u003e\n\t\u003c/h1\u003e\n\t\u003cp class=\"projectBadges info\"\u003e\n\t\t\u003cimg src=\"https://johng.io/badges/category/Library.svg\" alt=\"Project category\" title=\"Project category\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/github/languages/top/twocaretcat/tally-ts.svg\" alt=\"Language\" title=\"Language\"\u003e\n\t\t\u003cimg src=\"https://img.shields.io/github/repo-size/twocaretcat/tally-ts.svg\" alt=\"Repository size\" title=\"Repository size\"\u003e\n\t\t\u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/twocaretcat/tally-ts.svg\" alt=\"Project license\" title=\"Project license\"/\u003e\u003c/a\u003e\n\t\t\u003ca href=\"https://github.com/semantic-release/semantic-release\"\u003e\u003cimg src=\"https://img.shields.io/badge/semantic--release-conventionalcommits-e10079?logo=semantic-release\" alt=\"Semantic Release\" title=\"Semantic Release\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\t\u003cp class=\"projectBadges status\"\u003e\n\t\t\u003ca href=\"https://github.com/twocaretcat/tally-ts/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/twocaretcat/tally-ts.svg\" alt=\"Latest release\" title=\"Latest release\"/\u003e\u003c/a\u003e\n\t\t\u003ca href=\"https://jsr.io/@twocaretcat/tally-ts\"\u003e\u003cimg src=\"https://jsr.io/badges/@twocaretcat/tally-ts\" alt=\"View package on JSR\" title=\"View package on JSR\" /\u003e\u003c/a\u003e\n\t\t\u003ca href=\"https://jsr.io/@twocaretcat/tally-ts\"\u003e\u003cimg src=\"https://jsr.io/badges/@twocaretcat/tally-ts/score\" alt=\"View package on JSR\" title=\"View package on JSR\" /\u003e\u003c/a\u003e\n\t\t\u003ca href=\"https://www.npmjs.com/package/@twocaretcat/tally-ts\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@twocaretcat/tally-ts\" alt=\"View package on npmjs\" title=\"View package on npmjs\"/\u003e\u003c/a\u003e\n\t\u003c/p\u003e\n\t\u003cp class=\"projectDesc\"\u003e\n\t\tA TypeScript word counting library. Count the number of characters, words, sentences, paragraphs, and lines in your text instantly with tally-ts\n\t\u003c/p\u003e\n\t\u003cbr/\u003e\n\u003c/div\u003e\n\n## 👋 About\n\n\u003e [!NOTE]\n\u003e We use the terms _**graphemes**_ and _**characters**_ interchangeably in this README, although technically we are\n\u003e counting Unicode grapheme clusters rather than Unicode characters.\n\n**tally-ts** is a TypeScript library that uses modern APIs like `Intl.Segmenter` to count the number of characters,\nwords, paragraphs, and lines in the input. It can also show breakdowns for different types of characters like letters,\ndigits, spaces, punctuation, and symbols/special characters.\n\n### Features\n\n- **🧮 View text metrics:** Count the number of characters, words, sentences, paragraphs, and lines in your text.\n- **📊 View character composition:** View the number of spaces, digits, letters, punctuation, and symbols/special\n  characters in the input.\n- **🌍 Multilingual support:** Uses `Intl.Segmenter` for accurate word and character segmentation across many languages\n  and scripts.\n- **👨🏻‍💻 Open-source:** Know how to code? Help make **tally-ts** better by contributing to the project on GitHub, or copy\n  it and make your own version!\n\n### Use Cases\n\n- **📚 Students \u0026 Educators:** Check essay lengths and assignment limits quickly and accurately.\n- **✍️ Writers \u0026 Bloggers:** Track writing progress and optimize structure for readability.\n- **📄 Legal \u0026 Business Professionals:** Ensure documents meet required character or word counts.\n- **📱 Social Media Managers:** Stay within platform limits for tweets, posts, and bios.\n- **🧪 Developers \u0026 Testers:** Analyze input strings and view line counts for code and data.\n- **🌐 SEO Specialists:** Optimize content length for meta descriptions, headings, and body text.\n\n## 📦 Installation\n\n\u003e [!TIP]\n\u003e JSR has some advantages if you're using TypeScript or Deno:\n\u003e\n\u003e - It ships typed, modern ESM code by default\n\u003e - No need for separate type declarations\n\u003e - Faster, leaner installs without extraneous files\n\u003e\n\u003e You can use JSR with your favorite package manager.\n\nThis package is available on both [JSR](https://jsr.io/@twocaretcat/tally-ts) and\n[npm](https://www.npmjs.com/package/@twocaretcat/tally-ts). Install it using your preferred package manager:\n\n\u003cdetails\u003e\n\u003csummary\u003e🦕 Deno\u003c/summary\u003e\n\n```bash\ndeno add jsr:@twocaretcat/tally-ts     # JSR (recommended)\n```\n\n```bash\ndeno add npm:@twocaretcat/tally-ts     # npm\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e🥖 Bun\u003c/summary\u003e\n\n```bash\nbunx jsr add @twocaretcat/tally-ts     # JSR\n```\n\n```bash\nbun add @twocaretcat/tally-ts          # npm\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e🟢 npm\u003c/summary\u003e\n\n```bash\nnpx jsr add @twocaretcat/tally-ts      # JSR\n```\n\n```bash\nnpm install @twocaretcat/tally-ts      # npm\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e🟧 pnpm\u003c/summary\u003e\n\n```bash\npnpm i jsr:@twocaretcat/tally-ts       # JSR\n```\n\n```bash\npnpm add @twocaretcat/tally-ts         # npm\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e🧶 yarn\u003c/summary\u003e\n\n```bash\nyarn add jsr:@twocaretcat/tally-ts     # JSR\n```\n\n```bash\nyarn add @twocaretcat/tally-ts         # npm\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e🖇 vlt\u003c/summary\u003e\n\n```bash\nvlt install jsr:@twocaretcat/tally-ts  # JSR\n```\n\n```bash\nvlt install @twocaretcat/tally-ts      # npm\n```\n\n\u003c/details\u003e\n\n## 🕹️ Usage\n\n\u003e [!WARNING]\n\u003e **Some Caveats:**\n\u003e\n\u003e - This library relies on the `Intl.Segmenter` API (or a compatible replacement) to split the input into graphemes,\n\u003e   words, and sentences. Thus, the exact behavior and reproducibility of output counts depend on the JavaScript runtime\n\u003e   used. Results may vary between browsers, Node versions, or polyfills.\n\u003e - There may be slight variations between the counts generated by **tally-ts** and other libraries due to differences\n\u003e   in how they are implemented.\n\u003e - Languages like Chinese that do not have clearly defined words may have inaccurate word counts due to the\n\u003e   segmentation algorithm used. If you need consistent or linguistically precise segmentation for these languages, use\n\u003e   a dedicated tool instead. For Chinese, see [Jieba](https://github.com/fxsjy/jieba),\n\u003e   [Stanford Segmenter](https://nlp.stanford.edu/software/segmenter.shtml), or\n\u003e   [pkuseg](https://github.com/lancopku/pkuseg-python).\n\n### Getting Started\n\nTo get started, import the `Tally` class and create a new instance of it. I recommend setting the locale like so:\n\n```ts\nimport { Tally } from 'tally-ts';\n\nconst tally = new Tally({ locales: 'en' });\n```\n\n### Counting Sentences \u0026 Words\n\nUse individual methods to get counts for sentences and words:\n\n```ts\ntally.countWords('How are you?');\n// → { total: 3 }\n\ntally.countSentences('¿Como estas?');\n// → { total: 1 }\n```\n\n### Counting Graphemes\n\nYou can get the number of graphemes (characters) the same way:\n\n```ts\ntally.countGraphemes('Hello world!');\n// → {\n//     total: 12,\n//     by: {\n//       spaces: { total: 1 },\n//       letters: { total: 10 },\n//       digits: { total: 0 },\n//       punctuation: { total: 1 },\n//       symbols: { total: 0 },\n//     },\n//     related: {\n//       paragraphs: { total: 1 },\n//       lines: { total: 1 },\n//     }\n//   }\n```\n\nThis method has some extra features. You can access breakdown counts of the graphemes by type:\n\n```ts\nconst result = tally.countGraphemes('Hi there!');\n\nconsole.debug(result.by);\n// → {\n//     spaces: { total: 1 },\n//     letters: { total: 7 },\n//     digits: { total: 0 },\n//     punctuation: { total: 1 },\n//     symbols: { total: 0 }\n//   }\n```\n\nAs well as related features that were computed at the same time:\n\n```ts\nconsole.debug(result.related);\n// → {\n//     paragraphs: { total: 1 },\n//     lines: { total: 1 }\n//   }\n```\n\n### Kitchen Sink\n\nTo get all counts at once, use the `countAll()` method:\n\n```ts\nconst all = tally.countAll(`Hello world!\\n\\nThis is a test.`);\n\nconsole.debug(all);\n/* →\n{\n  graphemes: {\n    total: 27,\n    by: {\n      spaces: { total: 4 },\n      letters: { total: 20 },\n      digits: { total: 0 },\n      punctuation: { total: 1 },\n      symbols: { total: 0 },\n    },\n    related: {\n      paragraphs: { total: 2 },\n      lines: { total: 3 },\n    }\n  },\n  words: { total: 5 },\n  sentences: { total: 2 },\n  paragraphs: { total: 2 },\n  lines: { total: 3 }\n}\n*/\n```\n\n## 🤖 Advanced Usage\n\n### Setting a Locale\n\nYou can pass a locale (or an array of locales) via the `locales` option. This value is forwarded directly to\n`Intl.Segmenter` and determines how the input string is split into graphemes, words, and sentences:\n\n```ts\n// Single locale\nnew Tally({ locales: 'en' });\n\n// Multiple locales (preference order)\nnew Tally({ locales: ['fr-CA', 'fr'] });\n```\n\nIf `locales` is not provided, `Intl.Segmenter` will resolve the runtime's best locale automatically.\n\n### Getting the Resolved Locale\n\n\u003e [!NOTE]\n\u003e Even if you provide a locale, the resolved locale may be different if `Intl.Segmenter` doesn't support the one you've\n\u003e provided. In this case, another locale may be picked automatically.\n\nIf you didn't provide a locale, you might want to know which locale was actually used by `Intl.Segmenter`. You can get\nit by like so:\n\n```ts\nconst tally = new Tally();\n\nconsole.debug(tally.getResolvedLocale());\n// → \"en-US\"\n```\n\n### Using a Custom `Segmenter` Implementation\n\nIf your environment doesn't support `Intl.Segmenter` (or the exact locale you want to use), you can provide a custom\nimplementation or polyfill instead:\n\n```ts\nnew Tally({ Segmenter: SomeSegmenter });\n```\n\nThis is also useful if you want to get consistent results across different runtimes. If you don't provide a segmenter,\nwe will try to use the native `Intl.Segmenter` implementation.\n\nInternally, we will call the constructor of `Segmenter` to create segmenters of different granularities.\n\n## ⚠️ Usage (legacy)\n\n\u003e [!WARNING]\n\u003e **Deprecated:** The legacy implementation is no longer maintained and it has limited support for languages other than\n\u003e English. Use the class-based `Tally` API instead if possible.\n\nThe legacy implementation exposes a single function, `getCounts()`, that can be used to get the number of characters,\nwords, sentences, paragraphs, lines, spaces, letters, digits, and symbols at once:\n\n```ts\nimport { getCounts } from 'tally-ts/legacy';\n\nconst counts = await getCounts(`Hello world!\\n\\nThis is a test.`);\n\nconsole.debug(counts);\n/* →\n{\n  characters: 27,\n  words: 5,\n  sentences: 2,\n  paragraphs: 2,\n  lines: 3,\n  spaces: 4,\n  letters: 20,\n  digits: 0,\n  symbols: 1\n}\n*/\n```\n\nYou can provide an optional locale to improve segmentation accuracy for non-English text:\n\n```ts\nconst counts = await getCounts(`Hello world!\\n\\nThis is a test.`, 'de-DE');\n```\n\nNote that the this only affects the segmentation of characters. If your language doesn't use spaces to separate words or\nuses letters outside of the ASCII range, for example, you will still not get accurate results. For multilingual\ncounting, use the class-based `Tally` API instead.\n\n## 🧠 Implementation Details\n\n\u003e [!NOTE]\n\u003e In this section, we refer to words, graphemes, spaces, lines, etc. as **_tokens_** for simplicity.\n\nHere's some more details about how **tally-ts** does its magic.\n\n### Algorithm\n\nThe class-based implementation uses `Intl.Segmenter` for locale-aware text segmentation at three granularities:\n\n- **grapheme** with `countGraphemes()`\n- **word** with `countWords()`\n- **sentence** with `countSentences()`\n\nEach segmenter operates independently, and the results are combined when using `countAll()`.\n\nThe counting functions are implemented as single-pass parsers for performance reasons. Each grapheme in the input string\nis classified using Unicode General Categories (e.g., `\\p{L}`, `\\p{Nd}`, `\\p{Zs}`), providing accurate results for all\nlanguages and scripts supported by the platform’s ICU data.\n\nHere’s how counts are determined for each token type:\n\n| Count Type      | Description                                                                                                                                                                                                                                                                                         |\n| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **grapheme**    | A **user-perceived character** as defined by `Intl.Segmenter` with `granularity: \"grapheme\"`. Multi-codepoint characters (e.g., emojis, accented letters, combined scripts) are counted as one. **Examples:** `a`, `é`, `😊`, `👩‍🚀`, `貓`.                                                         |\n| **word**        | Counted using `Intl.Segmenter` with `granularity: \"word\"`. Each segment where `isWordLike` is `true` increments the word count. This is locale-aware and works for non-Latin scripts (e.g., Chinese, Arabic). **Examples:** `\"Hello world\" → 2`, `\"你好世界\" → 1`.                                  |\n| **sentence**    | Counted using `Intl.Segmenter` with `granularity: \"sentence\"`. Each non-empty segment increments the sentence count. Works for punctuation and locale rules (e.g., handling `¿` and `！`).                                                                                                          |\n| **space**       | A grapheme that matches the Unicode **Space Separator** category (`\\p{Zs}`). Includes ordinary spaces and non-breaking spaces. **Examples:** `' '`, `\\u00A0`.                                                                                                                                       |\n| **letter**      | A grapheme in the Unicode **Letter** category (`\\p{L}`). Includes characters from all alphabets. **Examples:** `A`, `ß`, `д`, `あ`, `م`.                                                                                                                                                            |\n| **digit**       | A grapheme in the Unicode **Decimal Digit** category (`\\p{Nd}`). Works across scripts (e.g., Arabic-Indic, Devanagari). **Examples:** `0`, `९`, `٢`.                                                                                                                                                |\n| **punctuation** | A grapheme in the Unicode **Punctuation** category (`\\p{P}`). **Examples:** `.`, `,`, `!`, `¿`, `“”`.                                                                                                                                                                                               |\n| **symbol**      | A grapheme in the Unicode **Symbol** category (`\\p{S}`). Includes math, currency, emoji, and miscellaneous symbols. **Examples:** `+`, `$`, `©`, `🔥`, `™`.                                                                                                                                         |\n| **line**        | Determined by newline graphemes (`'\\n'`). Each newline increments the line count. A final line is counted even if the text doesn’t end with a newline, unless the input is empty, in which case the line count is 0.                                                                                |\n| **paragraph**   | A non-empty, non-newline string, separated from other paragraphs by one or more newline characters. A trailing paragraph is counted even if the text doesn’t end with a newline, unless the input is empty, in which case the paragraph count is 0. **Example:** `\"Hello\\n\\nWorld\"` → 2 paragraphs. |\n\n### Legacy\n\nThe legacy implementation exposes a single function, `getCounts()`, that can be used to get the number of characters,\nwords, sentences, paragraphs, lines, spaces, letters, digits, and symbols at once.\n\n#### Algorithm\n\nThe counting function is implemented as a single-pass parser for performance reasons. State transitions (sentence\nterminator → letter, letter → space, etc.) are used to determine when to increment the counts for each token type.\n\nThe following characters are used to separate tokens:\n\n- **Space:** `' '`\n- **Newline:** `\\n`\n- **End Mark:** `.`, `!`, `?`\n\n**End of Input** can also be considered a separator because words, sentences, paragraphs, and lines at the end of the\ninput are counted even if not specifically terminated. For example, `Something` is counted as a word, sentence,\nparagraph, and line.\n\nHere is an overview of how we determine the counts for each token type:\n\n| Count Type    | Description                                                                                                                                                                                                                             |\n| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **character** | A Unicode **grapheme cluster** (user-perceived character), as determined by `Intl.Segmenter`. Using this method, Emojis and other multi-codepoint characters are counted as a single character. **Examples:** `a`, `2`, `!`, `🔥`, `貓` |\n| **word**      | A contiguous sequence of one or more **letters or digits** followed by a **space**, **end mark**, or **newline**. Symbols by themselves are not considered words. **Examples:** `space`, `Whoa!`, `newline\\n`, `42`.                    |\n| **sentence**  | A contiguous sequence of one or more **words** followed by an **end mark**. **Example:** `Hello, world!`, `20 93.`.                                                                                                                     |\n| **paragraph** | A contiguous sequence of one or more **sentences** followed by a **newline**. **Examples:** `The quick brown cat jumps over the lazy dog\\n`, `Hello world! Bye world!\\n`, `42\\n`.                                                       |\n| **space**     | A literal space character (`' '`). Other whitespace (ex. tabs, newlines) are not included.                                                                                                                                              |\n| **letter**    | A character in the ASCII ranges A–Z or a–z. **Examples:** `A`, `j`, `z`.                                                                                                                                                                |\n| **digit**     | A character in the ASCII range 0-9. **Examples:** `0`, `5`, `9`.                                                                                                                                                                        |\n| **symbol**    | A non-letter, non-digit, non-space, non-newline character. This includes emojis, symbols, punctuation, and most whitespace. **Examples:** `,`, `%`, `#`, `😊`, `貓`, `\\t`.                                                              |\n| **line**      | A literal newline character (`\\n`).                                                                                                                                                                                                     |\n\n## 🛟 Support\n\nNeed help? See the [support resources](https://github.com/twocaretcat/.github/blob/main/docs/SUPPORT.md) for information on how to:\n\n- request features\n- report bugs\n- ask questions\n- report security vulnerabilities\n\n## 🤝 Contributing\n\nWant to help out? Pull requests are welcome for:\n\n- feature implementations\n- bug fixes\n- translations\n- documentation\n- tests\n\nSee the [contribution guide](../../contribute) for more details.\n\n## 🧾 License\n\nCopyright © 2025 [John Goodliff](https://johng.io/r/tally-ts) ([@twocaretcat](https://github.com/twocaretcat)).\n\nThis project is licensed under the MIT license. See the [license](LICENSE) for more details.\n\n## 🖇️ Related\n\n### Recommended\n\nOther projects you might like:\n\n- **👤 [Tally Chrome Extension](https://github.com/twocaretcat/Tally-Extension)**: A Chrome extension to easily count\n  the number of words, characters, and paragraphs on any site\n\n### Used By\n\nNotable projects that depend on this one:\n\n- **👤 [Tally](https://github.com/twocaretcat/Tally)**: A free online tool to count the number of characters, words,\n  paragraphs, and lines in your text. **Tally** uses this library to compute counts\n\n### Alternatives\n\nSimilar projects you might want to use instead:\n\n- **🌐 [Alfaaz](https://github.com/thecodrr/alfaaz)**: An alternative multilingual word counting library with less\n  features, but faster execution\n\n## 💕 Funding\n\nFind this project useful? [Sponsoring me](https://johng.io/funding) will help me cover costs and **_commit_** more time\nto open-source.\n\nIf you can't donate but still want to contribute, don't worry. There are many other ways to help out, like:\n\n- 📢 reporting (submitting feature requests \u0026 bug reports)\n- 👨‍💻 coding (implementing features \u0026 fixing bugs)\n- 📝 writing (documenting \u0026 translating)\n- 💬 spreading the word\n- ⭐ starring the project\n\nI appreciate the support!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwocaretcat%2Ftally-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwocaretcat%2Ftally-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwocaretcat%2Ftally-ts/lists"}