# Owner: glow
# KeyID: E65A8520F36AEE13CFE4F56BEB8FE331063A4794
# Key: https://glow.li/pgp
# Verify: curl "https://glow.li/posts/critter/index.html.asc" | gpg
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
+++
{
"css": ["critter.css"],
"date": "2026-10-13",
"description": "A CLI and browser toy inspired by Tamagotchi.",
"excerpt_separator_text": "More info and installation instructions",
"fedi-link": "https://blob.cat/notice/BBNNRaPp5GCpAmfgLA",
"layout": "post",
"sharingimage": "media/images/screenshot-critter",
"tags": [
"Technology",
"Showcase",
"Node.Js",
"JavaScript",
"Project",
"Nostalgia",
"CLI",
"Terminal",
"Simulation",
"Game",
"Interactive"
],
"title": "Critter: A virtual pet for your terminal"
}
+++
I recently bought one of these retro [Tamagotchi](https://en.wikipedia.org/wiki/Tamagotchi) devices. For fun, I made a CLI/browser toy that's very similar. Go ahead and use the buttons to feed the hungry [Critter](https://github.com/Neo-Oli/critter). But it works best when installed as a CLI tool.
[toc]
## Context
[](media/images/big/tamagotchi)
Here's the Tamagotchi I recently bought. It's a reproduction, not an original.
## Usage
You can find installation instructions in the [repository](https://github.com/Neo-Oli/critter). After installation, create your critter with `critter new`.
```bash
$ critter new
⠀⠀⠀⠀⠀▄▀▀▀▄
⠀⠀⠀⠀▄▀▄⠀⠀▀▄
⠀⠀⠀▄▀⠀⠀⠀▀⠀▀▄
⠀⠀⠀▀▄⠀▀⠀▄⠀▄▀
⠀⠀⠀⠀▀▄▄▄▄▄▀
A 0 seconds
```
After a couple of minutes, it will hatch. Check the status with just `critter`. It'll probably be hungry. Feed it with `critter feed`.
`critter --help` will show you all the commands. This project works best with a [Nerd Font](https://www.nerdfonts.com/). If you don't have one installed, pass the `-n` flag to use the fallback text string instead of icons.
## Integrations
### Short output
Looking to integrate it into your status bar or similar? Try `critter -s`.
```bash
$ critter -s
ʕ•ᴥ•ʔ H▇ S▂ E▇ +█ T▂
```
### JSON output
For more advanced integrations, call `critter -j`. It gives you all sorts of information for more advanced use cases.
```
$ critter -j
{
"action": "idle",
"actionTime": 0,
"alert": false,
"Bars": "▇ ▂ ▇ █ ▂",
"Bars-nonerd": "H▇ S▂ E▇ +█ T▂",
"emoticon": "ʕ•ᴥ•ʔ",
"emoticon-nonerd": "ʕ•ᴥ•ʔ",
"Energy": 744064,
"Happy": 690411,
"Health": 1000000,
"Hunger": 298092,
"plain": "█▀█▄▄▄█▀█\n█ █\n█ █ █ █▄▄▄▄▄▄\n█ ▄ █ ██\n█▄▄▄▄▄▄▄█ █\n █ █\n █ █▀█ █▀▀█ █\n █▄▄█ █▄▄█ █▄█\n\nIDLE\n \n \n 2 days",
"plain-nonerd": "█▀█▄▄▄█▀█\n█ █\n█ █ █ █▄▄▄▄▄▄\n█ ▄ █ ██\n█▄▄▄▄▄▄▄█ █\n █ █\n █ █▀█ █▀▀█ █\n █▄▄█ █▄▄█ █▄█\n\nIDLE\nH │███▌ │ S │█▌ │\nE │███▌ │ + │█████│\nT │█ │ A 2 days",
"plainSprites": "█▀█▄▄▄█▀█\n█ █\n█ █ █ █▄▄▄▄▄▄\n█ ▄ █ ██\n█▄▄▄▄▄▄▄█ █\n █ █\n █ █▀█ █▀▀█ █\n █▄▄█ █▄▄█ █▄█",
"plainStats": "IDLE\n \n \n 2 days",
"plainStats-nonerd": "IDLE\nH │███▌ │ S │█▌ │\nE │███▌ │ + │█████│\nT │█ │ A 2 days",
"poo": false,
"short": "ʕ•ᴥ•ʔ ▇ ▂ ▇ █ ▂",
"short-nonerd": "ʕ•ᴥ•ʔ H▇ S▂ E▇ +█ T▂",
"Toilet": 183458
}
```
Want to know when your critter is hungry, sad, soiled, etc.? Periodically check the `alert` property.
```
$ critter -j | jq .alert
true
```
After reading an alert, call `critter dismiss` to clear it.
For example, a cron job or integration should call `critter dismiss` after sending the notification.
## Automated tests
One of the cool things about the project are the automated tests. With them dozens of critters are simulated to see how long they survive in certain conditions. Though I still grapple with the moral implication of spawning dozens of critters only to let them automatically die. It's probably fine.
```
> dies within the configured low-happiness health schedule
Critter died after 5 days, 18 hours, 53 minutes, 20 seconds (500000 seconds total).
> dies within the configured zero-happiness health schedule
Critter died after 2 days, 21 hours, 26 minutes, 40 seconds (250000 seconds total).
> dies within a week with only six-hour meals shifted by -60 minutes
Critter died after 2 days, 9 hours, 5 minutes, 0 seconds (205500 seconds total).
> dies within a week with only six-hour meals shifted by -30 minutes
Critter died after 2 days, 5 hours, 46 minutes, 0 seconds (193560 seconds total).
> dies within a week with only six-hour meals shifted by 30 minutes
Critter died after 2 days, 6 hours, 35 minutes, 0 seconds (196500 seconds total).
> dies within a week with only six-hour meals shifted by 60 minutes
Critter died after 2 days, 7 hours, 0 minutes, 0 seconds (198000 seconds total).
> dies within five days without commanded sleep despite feeding and cleaning
Critter died after 2 days, 11 hours, 41 minutes, 0 seconds (214860 seconds total).
> loses more health when poo cleaning is delayed
Critter died after 2 days, 3 hours, 49 minutes, 0 seconds (186540 seconds total).
Critter died after 1 days, 11 hours, 8 minutes, 0 seconds (126480 seconds total).
Critter died after 1 days, 6 hours, 18 minutes, 0 seconds (109080 seconds total).
> is dead by thirty days when only fed daily and poo is cleaned
Critter died after 1 days, 11 hours, 32 minutes, 0 seconds (127920 seconds total).
> is dead by thirty days when fed every five hours and poo is left
Critter died after 1 days, 6 hours, 18 minutes, 0 seconds (109080 seconds total).
> survives one day but dies within two when neglected from full health
Critter died after 1 days, 8 hours, 56 minutes, 0 seconds (118560 seconds total).
> hatches before dying within two days when neglected from birth
```
-----BEGIN PGP SIGNATURE-----
iQJPBAEBCgA5FiEE5lqFIPNq7hPP5PVr64/jMQY6R5QFAmrOasobFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMywyAAoJEOuP4zEGOkeUqdkP/iOU1VOI8VfTcd22yho8
FaScelQj17UG22ItYvT08QaXOvPJRkI3uqBeIYE4HeAyK7w46h06RvUG8xnnEug9
GeD8fclZMBmYgImq86zZ2Qdj1i5BgZONN1Bc5KMRYfq2RAOt3ip9KghDQh74dXGs
JcqoQSbWL0/pXbtJRZuaVKQUpLb7K9bEKhRbY9ZhLHPiN/Ck+7cLf0t4ZCEipSTC
WEli1TnGtjObTNQEWcgH9+cj7y1QOuNNr2/7U1bfuOrgA3oZQJZxiTZbfdW9C7W8
u0p0WDDKNQ8nI56sk7fnZRoKkPvFw7VlMjIPL+h7EXpW8NwgHUj2HIgfgouxBgB0
Br6fU60qhmgvMCfNM6B1csA9QA3fC/fVj5jHVULHmTu9zebLfpqF0GaFGIR/L4pH
1lc2nD/5RIBMiUTB9IFRz0vK5+7Nh7atc5huQQ51d1H4+9UbF4hqjxU2oXkw3uCB
cWAyj94YlujqyMQLPye/+hKz2ghL5Dh5JQEwYboDPe2hEm86mPZsQ9jpHnQ+7tSK
ThhrPH2bJiRD0ZzwRrxLehyLrcd0QDWFLD6fZWZ8rjH4EA1q9ez6S7GEZg6kRcvV
a2JJ6ZOpoacQmMvd7jauOOyUGQoxlRK/VqUyXx2uhxgrV/OISZTrmfF2eBLnyZtA
N9Y6f1lXXFePgZX2kvxpAdMS
=1gfi
-----END PGP SIGNATURE-----