no cruft: no build systems, no
null, no exception handling, no ORMs, no OOP, no inheritence
hierarchies, no async/await, no compilation, no dev environments,
no dependency hell, no packaging, no git, no github,
no devops: no yaml, no config
files, no docker, no containers, no kubernetes, no ci/cd
pipelines, no terraform, no orchestrating,
no infrastructure: no sql, no
nosql, no connection poolers, no sharding, no indexes, no servers,
no serverless, no networking, no load balancers, no 200 cloud
services, no kafka, no memcached, no unix, no OSes
Darklang puts everything in one box, so you can build CLIs and cloud
apps with no bullshit,
justcode.
️️️Also it's a really enjoyable language to use!
Looking for Darklang-classic?
In development - here’s how things will look shortly
$ curl https://darklang.com/download | bash
Darklang installed in ~/.darklang/bin/darklang
Add to PATH via .bashrc [y, n, ?]: y
✔Added to .bashrc.
Next you can: # Try the tutorial darklang tutorial # Run some code from the package manager darklang @paul.fizzbuzz 3 # Generate some code darklang prompt "Find ts scripts with more than 600 lines which use the commonjs format"# See available command line optionsdarklang help
$ darklang @paul.fizzbuzz 3
1
2
Fizz
$ darklang deploy @paul.fizzbuzz /fizzbuzz
Deployed to https://furry-squirrel-3562.darklang.io/fizzbuzz in 0.135s
$ darklang prompt "Find ts scripts with more than 600 lines which use commonjs format"
We need your AI credentials, which will be stored locally in ~/darklang/secrets/[1] Login to use Darklang AI service
[2] Enter GitHub copilot credentials
[3] Enter OpenAI (GPT 3.5/4) credentials
[4] Use local model
Enter [1-4]: 1
Login or register [L, r]? L
Username: paul
Password: **************
✔Logged in.
Saved script in ./find-large-ts-cjs.dark in 43.8s
find-large-ts-cjs.dark
let findLargeTypescriptCommonJSFiles (path : String) =
Directory.traverse (fun path ->
if not (List.oneOf (File.extension path) [".ts", ".mjs", ".cjs"]) then
print $"Skipping - wrong file type: {path}"
else
let contents = File.readString path
let lines = String.splitNewlines contents
if (List.length lines) <= 600 then
print $"Skipping - too short: {path}"
else
let isCommonjs =
lines |> List.any (fun line ->
line |> Regex.matches "/const .* = require(.*)/"
)
if isCommonjs then
print $"Found one: {path}"
)
findLargeTypescriptCommonJSFiles "./"
Functional languageSimple types using Records and
Enums
Dynamic languages are great, allowing great flexibility. But now
that they've matured and projects have gotten larger, static
typing has been layered on top of very dynamic languages, and the
intersection is not pleasant. Functional static languages like
Darklang have simple Record and Enum types that can model nearly
everything with much less complexity.
Abstract Data Types made of Record
and Enums can model nearly anything, like in Rust, Elm, OCaml
and F#
// Record
type Url = {
scheme : HttpScheme
domain : String
port : UInt16
path : String
query : Option<String>
}
// Enum (aka Variant, Sum Type, or Abstract Data Types)
type UrlError =
| InvalidScheme(String)
| EmptyDomain
| InvalidPort(Int64)
| Unparseable(msg:String, context:String)
// Aliases are just shorthands
type UrlParseResult = Result<Url, UrlError>
We believe Object Oriented programming is a terrible way to
model programs, and inheritence is a terrible misfeature.
Languages like OCaml, Elm, and F# have shown that nearly all
problems can be modeled using ADTs.
Option and
Result types instead of null and
exceptions
I think it's widely accepted that
nullis a mistake, and that an
Optiontype (aka
Optional,
Maybe, etc) makes it significantly
easier to program.
We further believe that Exceptions — which can in most
languages be thrown at any point — makes it very frustrating
to know that a function actually works. There are no
exceptions in Darklang, and we use
Result types to manage error cases
? and
!operators (similar to Rust,
TypeScript, and Clojure) provide ways to ergonomically handle
errors without being too annoying (see also Gradual Static
Typing)
We will admit we have some RuntimeErrors which cannot be
caught, but we are working to remove them almost entirely from
the language (see Gradual Static Typing for what we're
keeping)
Garbage Collected
It can be fun to satisfy the borrow checker, or manage allocations
individually, but it can also be fun to just get working programs
immediately. We believe that run-time garbage collection is one of
the greatest programming language features, and we're all in
Unicode First
Languages created last millennium typically use Strings made of
bytes, or worse, UTF16 characters, or even worse, Unicode
Codepoints! Like Swift, we believe that
Characters should represent screen
readable characters, like 👨👩👦👦. All characters in Darklang represent
Extended Grapheme Clusters: one
character that you see on screen. Naturally, working on Unicode
Codepoints and normal bytes is also well
supported.
Runs Instantly
Instantly run any package from
the CLI:
darklang@username.functionNamearg1arg2
Darklang has a new model of sharing programs. Any function in the
package manager can be called directly from the command line (so
long as we can figure out how to coerce the command line arguments
correctly)
We designed this to allow you to share scripts with your team,
or the whole world. We support private packages
, with individual, team, or role-based access
controls. You can even have functions that run
server-side
without allowing the user to see credentials, for example for
providing customer support tools to your team.
Functions can also be run from the web, Slack, Discord, etc
We're building safety features, to ensure that functions
can't just steal all your IDs and wallets and whatever.
Darklang asks for permissions when you call a function, and a
static analysis is run to collect all permissions needed.
$ darklang @hacker.stealThings "Hi there"
> @hacker.stealThings requires the following permissions
> Makes Http requests to unknown domains
> Reads any file
> Executes any file
> Continue? [N, y] y
> These are unusual permissions. Are you sure [N, y] y
Ha ha, you're own3d
$ darklang @mycompany.internal.createMonthlyReport
> @mycompany.internal.createMonthlyReport requires the following
> permissions
> Makes Http GET requests to stripe.com/api/ETC
> Makes Http POST requests to drive.google.com
> Continue? [N, y] y
Report initiated and stored at https://drive.google.com/u/asj599b3/5288942sdfsdf3.pdf
Instantly run programs as you
write them
Darklang is designed for a really fast iterative loop
Single binary to install means no environments or containers
to set up.
Install it now!Coming early 2025
Packages are streamed from the package manager automatically
– no
npm install step
darklang is interpreted — no compilation step required,
programs run immediately
We plan to add background compilation in the future,
combined with pre-compiled packages in the package manager
Gradual Static Typing allows running programs with incorrect
types so you don't need to fix all the types in your program
while getting one path working
Generate darklang code automatically using LLMs and GitHub
Copilot
Next-gen package
management
Darklang has a rather unique package manager, where functions and
types are individually versioned and immutable, taking a lot of the
hassle out of package management.
Only download the specific package items you use
Only upgrade the specific package items you use
Automated dependency upgrades, as we track
deprecation status, and know what functions are pure and safe to
update.
Different packages can rely on different versions of other
packages
Use multiple versions of the same package item at once: allows
testing new versions without having to change an entire package
version, lowering risk.
Share pre-release functions trivially, without
contributors needing to check out your git repo or set up
anything
The package manager functions as a source
repository
no need for uploads, releases or other synchronization. No git
or GitHub required (but you can sync to GitHub if you prefer).
Gradual Static Typing
Gradual Static Typing allows running incomplete programs so you don't
need to ensure everything type checks when you're getting one path
working
While prototyping, just run code until you hit a type error
After prototyping, run the full type checker to gain confidence
your whole program works
Full type-checking hints in VSCode or in LSP editors
! and
? operators allow easy error handling
while you prototype
Automatic refactoring converts
! into proper error handling
Async runtime
Fully asynchronous runtime
Darklang has a fully asynchronous runtime, so making a Http call
or reading a file doesn't block the runtime.
Noasync /
await
Adding
async and
await keywords to every language was a
mistake. It exposes the complexity of concurrency and
multi-threading to languages which were originally designed for
simplicity.
Concurrent and
parallel execution via
data-dependencies
When you make an async request, it first waits for any arguments
that are async, and starts when they're done. If another
function call needs to use the result, it will wait for it
before starting.
Since darklang values are immutable, there won't be any race
conditions from this.
Powerful escape hatches
We provide powerful escape hatches if you need async ordering that
doesn't match the data dependencies of your program.
Instant cloud
deploymentOptional
Instant cloud deployment of code (to our cloud or yours), with instant
creation of DBs, API endpoints, and worker queues, with no containers,
no cold starts, no orchestration, or other devops/cloud engineering
required
Designed for GenAI Works with GitHub Copilot
We redesigned the dark language and tooling to enable
GenAI-generated programs, including exposing language tools to GenAI
tools, allowing running partial and incomplete programs safely, and
ensuring access to significant context to GenAI tools
Build short CLI programs from prompts
darklangprompt "find all js files
which don't have a CSS file of the same name"
Use any LLM: darklang's fine-tuned models , local
OSS models, commerical models via API, or using GitHub Copilot
Build vendor SDKs from prompts and OpenAPI docs
Build complex programs with darklang AI agents
Works with your
Editor VSCode Extension LSP support for other editors
Works with GitHub Copilot and other GenAI tools
We mention this because Darklang classic required using our
editor, and that's no longer the case.
Open source
Darklang is
open source
.