tea is not a package manager.
tea is unified packaging infrastructure.
From the creator of brew
, tea is a standalone, binary download for all
platforms that puts the entire open
source ecosystem at your fingertips. Casually and effortlessly use the latest
and greatest or the oldest and most mature from any layer of any stack. Break
down the silos between programming communities, throw together scripts that
use entirely separate tools and languages and share them with the world with
a simple one-liner.
All you need is tea
.
Â
tea is pre v1. This means there may still be some niggles in day to day use. It also means that you should absolutely get involved. This is the key and golden time when getting involved is both easy and hugely fun. We look forward to meeting you đ
Â
Open source is a treasure troveâyet those chests are sealed with gnarly locks. tea is the key:
$ tea +rust-lang.org
tea: installing rust-lang.org and 13 other packages into a temporary sandbox
when done type: exit
tea $ cat <<EOF >hello.rs
fn main() {
println!("Hello World!");
}
EOF
$ rustc hello.rs -o hello
$ ./hello
Hello World!
tea $ exit
$ rustc
command not found: rustc
tea doesnât install packagesâat least not in a conventional senseâwe stow
them in ~/.tea
â . Your system remains pristine and isolated from teaâs
activity. But everything is right there when you need it.
â finally a package manager where all the packages are relocatable (like they should be).
teaâs +pkg
syntax puts the whole open source ecosystem at your fingertips,
if you stop at the +pkg
then the above happensâwe open a new shell with those
packages in the environmentâbut if you keep typing you can construct direct
usage:
$ tea +nodejs.org npx --yes browser-sync start --server
# ^^ one-liner to start a local web server with live reload
$ sh <(curl tea.xyz) +nodejs.org npx --yes browser-sync start --server
# ^^ same one-liner but works for anyone on the Internet
# (if tea is already installed, it uses it, if not it *doesnât* install tea,
# a temporary sandbox is created)
Compose everything, combine everythingâjust like the UNIX philosophy
envisaged. Which leads us to tea
-pipelines:
$ tea +gnu.org/wget wget -qO- tea.xyz/white-paper | tea +charm.sh/glow glow -
This example downloads our white paper and renders it with charmâs excellent
glow
terminal markdown renderer. This is a basic example, but UNIX has been
limited by the package manager for too long. Itâs a fundamental limitation
that tea is designed to overcome.
Notably, with
-X
syntax this can expressed more concisely:$ tea -X wget -qO- tea.xyz/white-paper | tea -X glow -
Itâs 202x so obviously we also can download scripts from the Internet:
$ sh <(curl tea.xyz) +charm.sh/gum https://github.com/charmbracelet/gum/blob/main/examples/demo.sh
Want to try out the latest version of node, but not sure if it will work with your project? tea makes it easy.
$ tea +nodejs.org^19 npm startOne liner to create a react app:
$ sh <(curl tea.xyz) -X npx create-react-app my-app
tea pipelines are so interesting we intend to have a dedicated showcase for them.
Â
$ tea https://gist.githubusercontent.com/i0bj/2b3afbe07a44179250474b5f36e7bd9b/raw/colors.go --yellow
tea: installing go 1.18.3
go: installing deps
go: running colors.go
âŠ
In this basic example we know to install go
first based on the file
extension. Obvious right? Which is why we didnât stop there:
$ tea favicon-generator.sh input.png
tea: installing image-magick, optipng, guetzli and 3 other packagesâŠ
âŠ
output: favicon-128.pngâŠ
$ cat favicon-generator.sh
#!/usr/bin/env tea
#---
# args: [/bin/sh, -e]
# dependencies:
# imagemagick.org: 4
# optipng.sourceforge.net: 1
# [snip]âŠ
#---
tea reads a fileâs YAML front-matter, allowing you to roll in the entire open source ecosystem for your scripts, gists and one-liners. While it runs, the script has these dependencies in its environment, but the rest of your system will never know about them.
We also know a little more magic:
$ tea -X node
tea: installing [email protected]
Welcome to Node.js v18.9.1.
Type ".help" for more information.
>
Typically tea
uses fully-qualified-names for packages, but we know what
tools they provide, so as long as you know what tool youâre looking for we can
figure out the rest.
--- dependencies: nodejs.org: 19 npmjs.com: package.json: dependencies: react: ^18 ---
Â
$ deno
zsh: command not found: deno
$ echo $PATH
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin
$ cd my-project
$ deno
tea: installing deno.land^1.22
deno 1.27.0
> ^D
$ env
PATH=~/.tea/deno.land/v1.27.0/bin:/usr/bin:/bin
SRCROOT=/src/my-project
VERSION=âŠ
âŠ
What is this sourcery?
tea uses a shell hook to insert the precise tooling your project needs into your shell environment. Development is now containerized at the package manager level. No longer do you need to worry about your team being on different versions of foundational tooling nor do you need to worry about system level updates breaking different projects youâre working on.
There are thousands of version managers for the thousands of tools they support. Probably itâs time we stopped that duplicated effort.
Projects can specify precisely what they need and you can install those requirements precisely be it today, tomorrow or in ten years.
In the above example if
deno
is not yet installed we insert a hook so trying to execute it will install it first.
PSA: Stop using Docker
Docker is great for deployment and cross compilation, but⊠letâs face it: it sucks for dev.
Docker stifles builders. It constricts you; youâre immalleable; tech marches onwards but your docker container remains immobile. Nobody knows how to use
docker
. Once thatDockerfile
is set up, nobody dares touch it.And letâs face it, getting your personal dev and debug tools working inside that image is incredibly frustrating. Why limit your potential?
Keep deploying with Docker, but use tea to develop.
Then when you do deploy you may as well install those deps with tea.
Frankly, tea is properly versioned unlike system packagers, so with tea your deployments actually remain more stable.
You need 34 dependencies to compile our white-paper but with tea thereâs nothing to think about:
$ git clone https://github.com/teaxyz/white-paper
$ cd white-paper
$ make #â
tea: installing pandoc.org and 33 other dependenciesâŠ
âŠ
$ open tea.white-paper.pdf
Our white-paperâs dependencies are written in plain markdown in our README
.
tea sets up a virtual environment for them simply by stepping into the
directory.
â on macOS you may need to do
tea -S
first since we re-use the system make (we try to detect system installed deps) and thus we cannot intercept the call
- weâll automatically load and unload completions
- weâll allow customizations per package for your project
Â
Markdown has (justifiably) become the standard documentation format of development. How about instead of writing scripts with comments, we write documentation that can be run.
$ tea . # interprets `# Getting Started`, could also be `tea ./README.md`
tea: npm install
tea: npm start
$ sh <(curl tea.xyz) https://github.com/my/project
tea: cloningâŠ
tea: npm start
$ git clone https://github.com/my/project
$ cd project
$ tea build
tea: executing `# Build`
Using these scripts in CI is easy:
steps:
- uses: teaxyz/setup@v0
with:
target: build
Check out teaxyz/setup for all that you can do with our GitHub Action.
This is a limited set of first steps exploring the idea of executable markdown. We intend to sensibly build out concepts for making entire documents executable, and weâd like your help with that. Start a discussion about it.
Â
tea is a standalone binary so, if you like, you can just download it yourself. For a little more magicâ , however, we recommend our installer:
sh <(curl https://tea.xyz)
# âą asks you to confirm before it sets tea up in `~/.tea`
# âą asks you to confirm before adding one line to your `~/.shellrc`
# âą asks you to confirm before making a `/usr/local/bin/tea` symlink
â if you want teaâs virtual environment manager functionality, the installer is the easiest way.
In fact, the tea one-liner abstracts away installation:
$ sh <(curl tea.xyz) https://examples.deno.land/color-logging.ts
# works the same as:
$ tea https://examples.deno.land/color-logging.ts
# if tea is installed, our one-liner uses the tea installation, if itâs not
# installed then it **doesnât install tea** or any dependencies, it creates a
# sandbox and runs everything in there
Now in your blog posts, tweets and tutorials you donât have to start with any âhow to install teaâ preamble nor will they need to google anything. If they want to learn about tea first they can go to the same URL as theyâre curlâing. We already work on Linux, macOS, and WSL; soon weâll support Windows natively.
As a bonus, the installer also updates tea.
We get it! We hate installers. Thatâs why we package everything! If you donât want it, then we fully support you in that.
Installing Without the Installer
tea
is a single binary that you can install yourself. If you prefercurl dist.tea.xyz
for a plain/text listing of binary downloads for all platforms.On macOS you will probably need to unquarantine the binary:
$ xattr -d com.apple.quarantine ./teaYou can try it out from the download location, but you will probably want to move it to
/usr/local/bin
or another directory in yourPATH
if you want to âinstallâ it.Now
tea
âs installed you can omit any instance ofsh <(curl tea.xyz)
and instead use your locally installed copy oftea
.Our (optional) magic
PATH
restructuring requires a hook in your~/.zshrc
:add-zsh-hook -Uz chpwd(){ source <(tea -Eds) }If this sourcery seems a bit much, you can just use tea as an interpreter instead. eg.
tea npm start
will execute the correctnpm
for your environment.
Uninstalling tea
- You can delete everything under
~/.tea
- Thereâs also a one-liner added to your
~/.zshrc
you should remove.- Finally delete
/usr/local/bin/tea
Â
Youâre a developer, installing tools globally makes no sense. With tea the tools you need per project or script are available to that workspace as virtual environments. Our magic works from depths of libc to the heights of the latests fads in CSS precompilers. All versionsâ . All platformsâĄ.
â Weâre new software, give us time to achieve this promise.
⥠Windows (native, we support WSL), Raspberry Pi, BeOS, etc. coming soon!
When you cd
into a project in your terminal, tea sets up the environment so
your tools âjust workâ. To do this it looks for a dependencies table in
your README
.
Using the
README
may seem weird, but really it's the right place to document your dependencies. Typically in open source this information is barely documented, incorrectly documented or duplicated (incorrectly) in various hard to find places. No longer.Additionally this makes use of tea optional. Your team or your users can source your dependencies themselves if they want. It says right there in a human readable form in the
README
what they need to get.Umm, I hate this, can I use a different file?
You can use
package.json
instead:{ "tea": { "dependencies": [{ "nodejs.org": 18 }] } }We check
README.md
beforepackage.json
. You can force use ofpackage.json
by disabling magic with--muggle
.
For an example see our âdependenciesâ section (teaception: we use tea to build tea).
You can check what environment this generates with tea
:
tea --env --dump
--env
specifies that tea will generate an environment based on the source
control checkout. So if youâre using git weâll look around for a .git
directory and consider that the SRCROOT
for your project. Then we check the
README.md
there to gather the environment information.
tea attempts to further enhance your environment based on your workspace context:
Variable | Description |
---|---|
VERSION |
Extracted from the README |
SRCROOT |
We descend towards root until we find a source control marker, eg. .git |
MANPATH |
So man ⊠works for your deps |
We also provide eg. PKG_CONFIG_PATH
, LD_LIBRARY_PATH
, DEVELOPER_DIR
,
etc. so other tools can find your dependencies. We provide other variables for
convenience too, like GITHUB_SLUG
(extracted from your git remote
) which
can be surprisingly useful to automation scripts.
These variables are also available to tea Scripts.
Our shell magic controls this feature, if you donât want to add our one-liner to your shell rc then you can just
tea sh
in your project directory to get the same effectâalbeit more laboriously.
Â
You can use tea to execute pretty much any script from any location. Weâll auto-magically install the right interpreter (as an isolated virtual environmentâthere are no global consequences to your system).
$ tea my-script.py
tea sees the .py
file extension, so it installs the latest version of Python
and then executes the script.
If you want more control over the python version then we need to edit the scriptâs YAML front-matter, eg:
#!/usr/bin/env python
"""
---
dependencies:
python.org: ^2.7
---
"""
# snip âŠ
tea will run the script with the latest version of Python that is >=2.7 but less than 3.0. If it's not installed we grab it, otherwise we use what is available.
We also support args
and env
parameters which are useful for tools that
require a run
command like deno or go.
#!/usr/bin/env deno
/*---
dependencies:
deno.land: ^1.27
args:
- deno
- run
# we put the script filename on the end for you here
env:
foo: {{srcroot}}/bar
---*/
You can #!/usr/bin/env tea
, and youâd possibly choose this because tea can
do more than install dependencies. You may recall our earlier diatribe about
tools sticking to what theyâre good atâwe really believe this. Thus
having tools evolve to be configurable for project environments is something
we think should be left to us.
For example, deno
is a wonderful interpreter for JavaScript and TypeScript,
but it has no project configuration capabilities which means if you want to
use it for scripts you may have to mess around a little. We think deno should
stay this way, and instead we can use tea:
#!/usr/bin/env -S tea -E
/* ---
dependencies:
deno.land: ^1.18
args:
- deno
- run
- --allow-net
- --import-map={{ srcroot }}/import-map.json
# ^^ we provide {{srcroot}} which can be enormously useful for scripting
# note that you must use a `tea -E` shebang for this to work
--- */
// snip âŠ
Which would go like this:
$ pwd
/src
$ ./script.ts my-arg
tea: ~/.tea/deno.land/v1.18/bin/deno run \
--allow-net \
--import-map=/src/import-map.json \
/src/script.ts \
my-arg
When called with
-E
tea reads the virtual environment and injects any dependencies from there. Probably your project already specifies yourdeno
dependency, so the above YAML is possibly being redundant.
Â
tea
formalizes (in a CLI/TUI sense) the concept of magic.
In an environment where there is magic we try to be clever and infer what you want. Without magic we are strict and require precise specification of your intent.
You can disable magic by specifying --muggle
or exporting MAGIC=0
to your
shell environment.
The primary magic we apply is determining if you want to use your virtual
environment or not. Strictly tea --env
is required to inject it, but when
magic is enabled we try to figure out if you just wanted that. Our goal is
to be smart and useful for your productivity.
We do some magic per dependency. This is currently hard-coded logic in tea/cli
itself, but we intend to make it general with a magic.ts
file per package
in the pantry.
Currently magic is limited (and a great place for contributionsâ ).
For example, if we detect that your project is a GitHub Action we read the
action.yml
and make the right version of node available.
â is there a file that your environment or language always has and thus
tea
should know to add packages to that environment? Open a discussion or just go straight to contributing the PR! Magic lives inuseVirtualEnv.ts
.
Â
If you have suggestions or ideas, start a discussion. If we agree weâll move it to an issue. Bug fixes straight to pull request or issue please!
Probably the place youâll want to start is by supplementing the pantry.
tea
is written in TypeScript using deno.
git clone https://github.com/teaxyz/cli tea
cd tea
tea run foo # runs the local checkout passing `foo` as an argument
tea install-self # deploys the local checkout into your `~/.tea`
- We really need more tests!
- We need test coverage information
- More magic for dependencies, eg. knowing what version of node should be in
the env based on
.node-version
files used for other version managers.
There isnât a token yet but when itâs brewed itâs quite possible there will be a little something extra for those who helped build tea. đ¶âđ«ïž
Â
tea works differently. Itâs not âI want to install Freetypeâ itâs âI want to use Freetypeâ.
Look, weâre not idiots. We know there are occasions where a good olâ
brew install
is what you need. Soâfor nowâcontinue using brew install
.
Longer term, we have plans for an extensible commands system.
tea is a set of packaging primitives. We want you to build entirely new things on top of tea. We want to integrate tea into your existing build tools, we eventually want to be the authoritative packaging datastore (isnât it about time there was one of those?)
Coming soon is tea/cmd. tea/cli will expose forks of this repo as commands
the user can run utilizing the power of teaâs packaging primitives to do all
that they can imagine. Maybe itâll be you who writes the tea install
command? (If you do, try to do something new, eh? đ)
If you really want to put tea
through its paces, you can combine the search
magic with your shellâs âcommand not foundâ logic, to get automatic tea
lookups.
We list all packages at tea.xyz. Or open ~/.tea/tea.xyz/var/pantry
. We
agree this is not great UX.
We install compartmentalized packages to ~/.tea
.
We then suggest you add our one-liner to your shell .rc
and a symlink
for /usr/local/bin/tea
.
We might not have installed tea, if you used sh <(curl tea.xyz) foo
and tea
wasnât already installed, then you we only fetched any packages, including
tea, temporarily.
tea is creating new technologies that will change how open source is funded. tea/cli is an essential part of that endeavor and is released prior to our protocol in order to bootstrap our holistic vision.
We donât subscribe to any particular âwebâ at tea.xyz, our blockchain component will be an implementation detail that you wonât need to think about (but we think you will want to).
No. Software is a multi-trillion industry. We only have to skim a little off that to pay the entire open source ecosystem. Check out our white-paper for the deets.
Our packages are relocatable by default. Just keep the directory structure the same. And ofc. you are licensed to do so. Honestly we think you should absolutely bundle and deploy teaâs prefix with your software. We designed it so that it would be easier for you to do this than anything that has come before.
Start a discussion and weâll get back to you.
Â
Â
- Be nonâintrusive
donât interfere with our usersâ systems or habits
- Be âjust worksâ
our users have better things to do than fix us
- Error messages must be excellent
trust that if it comes to it, our users can fix things provided we give them a helping hand
- Be intuitive
being clever is goodâbut donât be so clever nobody gets it
- Resist complexity
rethink the problem until a simpler solution emerges
- Be fast
we are in the way of our usersâ real work, donât make them wait
If you got this error message, you need to install tea:
sh <(curl https://tea.xyz)
.
We donât aim to replace brew
, we see our offerings as somewhat
complementary. Still where we have overlapping features:
- tea doesnât require you install the Xcode Command Line Tools
- tea packages are relocatable
- tea aims to be zippier in all usage
- tea doesnât make global changes to your system
- tea aims to enhance the way you work, rather than impose the way you work
- tea installs independently for every user on the machine
- tea is somewhat decentralized and aims to be completely decentralized
- tea is a tight series of tight, easy-to-understand codebases
- tea starts building new releases for tools almost immediately
- teaâs packages are named in a fully-qualified manner
- teaâs philosophy is user-first and not tea-maintainer-first
Â
You can execute each of these with tea foo
where foo
is the name of the
section.
FIXME
would be nice to be able to specify tests here deno supports--filter
but that would require a little massaging.
export TMPDIR=${TMPDIR:-/tmp}
deno test \
--allow-net \
--allow-read \
--allow-env=SRCROOT,GITHUB_TOKEN,TMPDIR,TEA_PREFIX,MUGGLE,MAGIC,JSON,NUMPTY \
--allow-run \
--import-map=$SRCROOT/import-map.json \
--allow-write=$TEA_PREFIX/tea.xyz/var,$TMPDIR \
--unstable \
"$SRCROOT"/tests/**/*.test.ts
deno check \
--import-map="$SRCROOT"/import-map.json \
--unstable \
src/app.ts \
"$SRCROOT"/scripts/*.ts
deno run \
--import-map="$SRCROOT"/import-map.json \
--unstable \
--allow-all \
"$SRCROOT"/src/app.ts
OUT="$1"
if test -z "$OUT"; then
OUT="./tea"
else
shift
fi
deno compile \
--allow-read \
--allow-write \
--allow-net \
--allow-run \
--allow-env \
--unstable \
--import-map="$SRCROOT/import-map.json" \
--output "$OUT" \
"$@" \
"$SRCROOT/src/app.ts"
Installs this working copy into ~/.tea/tea.xyz/vx.y.z
.
tea compile "$TEA_PREFIX/tea.xyz/v$VERSION/bin/tea"
"$SRCROOT"/scripts/repair.ts tea.xyz
Project | Version |
---|---|
deno.land | ^1.27 |
tea.xyz | ^0 |
macOS >= 11 || linux:glibc >= 23
Â
Every programming language, every build system, every compiler, web server, database and email client seem to gravitate towards adding infinite features and complexity so that their users can do ever more and more.
This is contrary to the UNIX philosophy: tools should do one thing and âby being tight and focusedâ do it damn well. If they are composable and flexible then they can be combined, piped and leveraged into a larger, more capable toolbox. The Internet is built with this toolbox.
Nowadays every programming language reimplements the same set of libraries and tools because using a well-maintained, mature and portable library that lives higher up the stack adds too much complexity. This extends the adolescence of new languages, results in no single language even becoming truly state of the art and leads to degrees of duplication that make the open source ecosystem fragile. This is to the detriment of all software, everywhere.
tea removes this complexity and adds some much needed robustness for the good of the entire open source ecosystem, the larger Internet and the whole world of software.