Package managers prop up every developer’s stack. With great power comes great responsibility—but like—packagers sit beneath all other developer tools; couldn’t they do so much more?
We think so.
tea abstracts away packaging; its a universal virtual environment manager, a universal interpreter; it’s a universal dependency manager. tea makes packaging programmable by exposing it as a set of primitives that can be composed into entirely new tools. Change how you work. Change how your team works. Change how the world works.
tea is a universal virtual‑environment manager:
$ deno
zsh: command not found: deno
$ echo $PATH
/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin
$ cd my-project
$ deno
deno 1.22.1
> ^D
$ env
PATH=~/.tea/deno.land/v1.20.3/bin:/usr/bin:/bin
SRCROOT=/src/my-project
VERSION=…
…
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 dependencies…
…
$ open tea.white-paper.pdf
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.
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.
Fear not! This works with your other shit…
Fear not, this magic works with things like VSCode too (we don’t believe in forcing or restricting your choice of tooling).
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.
Keep deploying with Docker, but use tea to develop (and when you deploy, use tea to install your deps).
tea is a universal interpreter:
$ tea https://github.com/teaxyz/demos/blob/main/demo.go input.txt
tea: installing go 1.18.3
go: running demo.go
…
We infer interpreter from the extension, shebang, YAML front matter or open graph metadata (we’ve added packaging extensions).
Is this safe?
If you’re worried about executing scripts from the Internet: read them first! tea only executes what the script tells it to; the dependency requirements are embedded in the script as YAML front-matter.
tea is a universal dependency manager†:
$ tea https://github.com/teaxyz/demos/blob/main/ai-image-gen.py input.png
tea: installing python^3
pip: installing pytorch.org^1.11
…
ai-image-gen: optimizing output.png
$ curl https://github.com/teaxyz/demos/blob/main/ai.py
#!/usr/bin/env tea
# ---
# dependencies:
# python.org: ~3.8
# pypi.org/pytorch: ^1.11
# optipng.sourceforge.net: '*' # optipng will be in `PATH`
# ---
…
† we use the term dependency manager for tools like npm, pip, cargo and gem that install packages for programming languages. They are variants of package managers. tea blurs the line between these tools.
tea makes Markdown executable:
$ tea https://github.com/teaxyz/demos/favicon-cheat-sheet.md input.png
favicon: generating sizes
favicon: optimizing images with optipng
…
You can use this to make the instructions in your README
executable,
for both users and automation:
$ tea ./README.md # interprets `# Getting Started`
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`
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 is designed to remove this complexity for development, for deployment and for scripting.
Installing tea is easy:
sh <(curl https://tea.xyz)
# • only install files in `~/.tea`
# • makes you confirm you’re cool before it does that
In fact, the tea one-liner abstracts away installation:
$ sh <(curl https://tea.xyz) https://example.com/script.ts
# works the same as:
$ tea https://example.com/script.ts
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. And as soon as we enable cross platform support this one-liner will work for everyone, everywhere.
Installing Manually
tea
is a single binary that you can install yourself:curl -O https://dist.tea.xyz ~/.local/bin
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
tea only installs to
~/.tea
There’s also a one-liner added to your~/.zshrc
you should remove.
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, 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.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.
We also inject shell completions for your environment. coming soon
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.
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 tea
/* ---
tea:
env: true # †
dependencies:
deno.land: ^1.18
args:
- deno
- run
- --allow-net
- --import-map={{ srcroot }}/import-map.json
--- */
// snip …
Which would go like this:
$ pwd
/src
$ tea ./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
† specifying
env: true
is necessary to use{{ srcroot }}
later in the YAML. You would also use it for any project that has an environment your scripts might need. Probably your project already specifies yourdeno
dependency, so the above YAML is possibly being redundant.
tea is new software and not mature. If you are an enterprise, we don’t recommend using tea yet. If you are devshop or open source developer then welcome! Dig in 🤝.
We only support macOS currently, though the Linux binary works pretty well. Also, currently we require zsh.
We intend to be cross platform, this includes Windows (WSL and non-WSL), Raspberry Pi, all varieties of Linux. Building binaries for everything we support.
tea allows you to “get started” anywhere (just not quite yet).
tea uses the concept of magic. In an environment with 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.
We do magic per dependency by processing a magic.ts
in the pantry. For
example with deno
we extract your import-map
specification from any
.vscode/settings.json
we find in your virtual environment. Then if you
type deno
on the command line we automatically inject the import map. You
can supplement our magic by contributing to the pantry.
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!
When developing tea you often want to use that version as your primary tea install. We provide a script to achieve this:
git clone https://github.com/teaxyz/cli tea
cd tea
./scripts/self-install.ts
The script replaces /usr/local/bin/tea
with a deno
instantiation that runs
your checkout, (installing deno first ofc).
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
.
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).
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)
.
Project | Version |
---|---|
deno.land | ^1.18 |
tea.xyz | ^0 |
export TMPDIR=${TMPDIR:-/tmp}
deno test \
--allow-net \
--allow-read \
--allow-env=SRCROOT,GITHUB_TOKEN,TMPDIR,TEA_PREFIX \
--allow-run \
--import-map=$SRCROOT/import-map.json \
--allow-write="$TMPDIR" \
$SRCROOT/tests/*.ts
for x in scripts/*.ts src/app.ts; do
deno check --import-map=$SRCROOT/import-map.json $x
done