{"id":13775507,"url":"https://github.com/ickyicky/fasttyper","last_synced_at":"2026-04-03T21:01:10.336Z","repository":{"id":44467956,"uuid":"384720243","full_name":"ickyicky/fasttyper","owner":"ickyicky","description":"CLI program for practicing typing","archived":false,"fork":false,"pushed_at":"2024-05-24T11:56:31.000Z","size":5327,"stargazers_count":52,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-08T10:43:15.126Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ickyicky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-10T14:42:21.000Z","updated_at":"2025-09-02T15:32:45.000Z","dependencies_parsed_at":"2022-08-05T14:15:52.976Z","dependency_job_id":null,"html_url":"https://github.com/ickyicky/fasttyper","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/ickyicky/fasttyper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ickyicky%2Ffasttyper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ickyicky%2Ffasttyper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ickyicky%2Ffasttyper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ickyicky%2Ffasttyper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ickyicky","download_url":"https://codeload.github.com/ickyicky/fasttyper/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ickyicky%2Ffasttyper/sbom","scorecard":{"id":480422,"data":{"date":"2025-08-11","repo":{"name":"github.com/ickyicky/fasttyper","commit":"61a37706dbf82ebdf5ec764543c1a03907194a2b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: downloadThenRun not pinned by hash: doc/fasttyper.sh:8","Info:   0 out of   1 downloadThenRun dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 0.0.3 not signed: https://api.github.com/repos/ickyicky/fasttyper/releases/46025038","Warn: release artifact 0.0.3 does not have provenance: https://api.github.com/repos/ickyicky/fasttyper/releases/46025038"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2014-14 / GHSA-652x-xj99-gmcc","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2014-13 / GHSA-cfj3-7x9c-4p3h","Warn: Project is vulnerable to: PYSEC-2018-28 / GHSA-x84v-xcm2-53pg"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-19T16:27:43.714Z","repository_id":44467956,"created_at":"2025-08-19T16:27:43.714Z","updated_at":"2025-08-19T16:27:43.714Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31377106,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:53:18.093Z","status":"ssl_error","status_checked_at":"2026-04-03T17:53:17.617Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":[],"created_at":"2024-08-03T17:01:39.978Z","updated_at":"2026-04-03T21:01:10.317Z","avatar_url":"https://github.com/ickyicky.png","language":"Python","funding_links":[],"categories":["Productivity","\u003ca name=\"typing\"\u003e\u003c/a\u003eTyping test and practice"],"sub_categories":["Kubernetes"],"readme":"# fasttyper\n[![](https://github.com/ickyicky/fasttyper/blob/main/doc/demo.gif?raw=true)](https://github.com/ickyicky/fasttyper)\n\n# About\n\n_Fasttyper_ is minimalistic typing test based on user provided exercising text. It supports both reading from text files and stdin supporting wide range of usecases. The goal was to create it as simple as it can be, without any additional bloatware functionalities. That means that _Fasttyper_ doesn't come with build in test generator and you have to provide your own scripts generating tests. Some examples of such scripts are provided in [Usage section](#usage).\n\n# Table of contents\n\n  - [fasttyper](#fasttyper)\n  - [About](#about)\n  - [Installation](#installation)\n  - [Usage](#usage)\n  - [Running next test and stopping application](#running-next-test-and-stopping-application)\n  - [Configuring](#configuring)\n  - [Usage as module, piping stuff, custom scripts etc](#usage-as-module,-piping-stuff,-custom-scripts-etc)\n  - [When backspace does wierd shiet](#when-backspace-does-wierd-shiet)\n  - [Hiding cursor](#hiding-cursor)\n    - [Example scripts](#example-scripts)\n\n# Installation\n\n_Fasttyper_ is currently maintained on [PyPi](https://pypi.org/) Python Package Index. To install package simply use:\n\n`python3 -m pip install fasttyper`\n\n# Usage\n\nWith installation of fasttyper you should have new executable - `fasttyper`. It takes two optional positional arguments, amount of words and language (like in [Monkeytype's](https://github.com/Miodec/monkeytype): english, english_1k etc). Default amount of words is 25 and language is english. To run fasttyper simply call:\n\n```bash\nfasttyper\n```\n\nfrom command line. There are some available options:\n\n```\nusage: fasttyper [-h] [--config FILE] [--unclutter-backspace] [--no-cursor] [amount] [language]\n\npositional arguments:\n  amount                Amount of words\n  language              Language\n\noptions:\n  -h, --help            show this help message and exit\n  --config FILE, -c FILE\n                        configuration file\n  --unclutter-backspace, -b\n                        unclutter backspace, when it raises ctrl+backspace instead\n  --no-cursor, -n       disable cursors\n```\n\nI personally use alias:\n\n```\nalias ff='fasttyper -n`\n```\n\nbecause i don't like having cursor and i am too lazy to type fasttyper so i just type ff :)\n\n# Running next test and stopping application\n\nTo abandon test and start brand new one, press TAB.\n\nTo kill application (exit) press CTRL+C.\n\n# Configuring\n\nDefault configuration:\n\n```python\n{\n    \"user_input_valid_color\": 3,\n    \"user_input_invalid_color\": 2,\n    \"reference_text_color\": 9,\n    \"stats_template\": \"wpm: {stats.wpm:0.2f}, time: {stats.total_seconds:0.2f}s\",\n    \"stats_color\": 5,\n    \"stats_position\": \"top\",\n    \"summary_datafile\": \"~/.cache/fasttyper/datafile.csv\",\n    \"top_margin_percentage\": 40,\n    \"left_margin_percentage\": 35,\n    \"min_width\": 80,\n    \"lines_on_screen\": 3,\n    \"border\": 1,\n    \"logo\": \" ~ FastTyper ~ \",\n    \"logo_color\": 8,\n    \"resume_text\": \" press \u003cTab\u003e to continue, \u003cCtrl\u003eC to exit \",\n    \"resume_text_color\": 9,\n    \"summary_template\": (\n        \"wpm: {wpm:5.1f}   |   peak: {peak_wpm:5.1f}\",\n        \"raw: {raw_wpm:5.1f}   |   peak: {peak_raw_wpm:5.1f}\",\n        \"acc: {accuracy:5.1f}%  |   words: {correct_words}/{total_words}\",\n        \"time: {total_seconds:5.1f}s \",\n    ),\n    \"summary_centered\": True,\n    \"summary_color\": 9,\n    \"summary_lines\": 4,\n    \"summary_border\": 0,\n    \"random_capitalization\": 0,\n    \"random_punctuation\": 0,\n    \"sentence_mode\": False,\n    \"punctuation\": \",.?!;:\",\n    \"sentence_ending\": \".?!\",\n    \"amount\": 25,\n    \"language\": \"english\",\n    \"no_cursor\": False,\n    \"unclutter_backspace\": False,\n}\n```\n\nFasttyper by default looks for config file in: `$HOME/.config/fasttyper/config.json`. You can provide different location for config file with `--config` argument, for example: `--config=~/.fasttyper.json`. Config has to be a json dict. Available keys:\n\n- **user_input_valid_color** - integer, terminal color for valid text, by default it is 3\n- **user_input_invalid_color** - integer, terminal color for invalid text, by default it is 2\n- **reference_text_color** - integer, terminal color for reference text, by default it is 8\n- **stats_color** - integer, terminal color for stats text, by default it is 5\n- **summary_datafile** - datafile storing all stats, by default it is ~/.cache/fasttyper/datafile.csv\n- **top_margin_percentage** - integer, percentage of screen used for top margin, by default 30\n- **left_margin_percentage** - integer, percentage of screen used for left (and right) margin, by default 10\n- **lines_on_screen** - integer, number of lines to display on screen, by default 3\n\nAlso there are keys that override fault parameters for CLI args, like: amount and language will override Your default settings for runner, same goes for punctuation, sentence_mode etc.\n\nExample config file with all default values in available [here](https://github.com/ickyicky/fasttyper/blob/main/doc/example_config.json).\n\nOther example config files:\n\n```json\n{\"top_margin_percentage\": 40, \"left_margin_percentage\": 25}\n```\n\n```json\n{\"user_input_valid_color\": 5}\n```\n\n# Usage as module, piping stuff, custom scripts etc\n\n_Fasttyper_ is ran as an python module, so to execute it simply type:\n\n`python3 -m fasttyper`\n\nfrom cloned github repository, if you didn't [install](#installation) package from TestPyPi. \n\n_Fasttyper_ can open text files, which path should be provided as first and only argument to the module execution, for example:\n\n`python3 -m fasttyper example_text.txt`\n\nProgram also allows user to pipe text into it. Keep in mind, it only supports spaces and new line characters, so you won't be able to table tabs. For example, you can run _Fasttyper_ on fortune generated quote changing tabulators to spaces with sed:\n\n`furtune | python3 -m fasttyper`\n\nor if you want to randomize words from given file with shuf on for example all dictionaries in system:\n\n`shuf -n5 /usr/share/dict/* | python -m fasttyper`\n\nYou can use another similar projects set of words as well, for example to create test with 20 random words from [Monkeytype's](https://github.com/Miodec/monkeytype) english 100 dictionary use:\n\n`curl -s https://raw.githubusercontent.com/monkeytypegame/monkeytype/master/frontend/static/languages/english.json | python3 -c \"import sys, json; print('\\n'.join(json.load(sys.stdin)['words']))\" | shuf -n20 | python3 -m fasttyper`\n\nTo exit you can either finish test, use `KeyboardInterrupt` (CTRL+C) or tap **tab**. After you finish test, there will be summary printed, use enter to exit from it.\n\n# When backspace does wierd shiet\n\nSome terminal emulators send different values for key presses of backspace and ctrl+backspace. To fix it, simply add `b` flag like that: `python3 -m fasttyper -b`.\n\n# Hiding cursor\n\nTo hide the cursor, simply add `n` flag like that: `python3 -m fasttyper -n`.\n\n## Example scripts\n\n```sh\nfunction ff() {\n\tmkdir -p ~/.cache/fasttyper\n\tlocal amount=\"${1:-50}\"\n\tlocal language=\"${2:-english}\"\n\tlocal sfile=~/.cache/fasttyper/$language\n\tlocal source_path=https://raw.githubusercontent.com/Miodec/monkeytype/master/static/languages/$language.json\n\t[[ ! -f $sfile ]] \u0026\u0026 curl -s $source_path | python3 -c \"import sys, json; print('\\n'.join(json.load(sys.stdin)['words']))\" \u003e $sfile\n\twhile true\n\tdo\n\t\tshuf -n $amount $sfile | python3 -m fasttyper || break\n\tdone\n}\n```\n`ff 50 english_1k`\n\nThis shell function shuffles N words from cached word list, and if given word list doesn't exist it download's it. It runs in loop, but does exit from it if you exit fasttyper with CTRL+C.\n\nThe above script is available for download from doc folder.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fickyicky%2Ffasttyper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fickyicky%2Ffasttyper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fickyicky%2Ffasttyper/lists"}