- Dark is a new
- way of building serverless backends. Just code your backend, with no
- infra, framework or deployment nightmares. Build
- APIs,
- CRUD apps,
- internal tools and
- bots - whatever your backend
- needs.
-
-
-
- The classic version of darklang is still accessible but is currently
- in maintenance mode, with no ongoing development. Darklang-next is the
- next iteration of Dark, applicable to both the cloud runtime and to
- local scripts and CLIs
-
-
-
-
-
-
-
-
-
-
-
-
- Internal Tools & Bots
-
-
- Dark is ideal for quickly building slackbots and automating internal
- tools. Receive webhooks live, call out to 3rd party APIs, store
- data, and schedule jobs - while building no infrastructure.
-
-
-
-
-
-
-
- REST APIs & Webhooks
-
-
- Set up an API endpoint quickly enough to use it as a proof of
- concept during a call. Immediately see the data from a webhook to
- your endpoint. Call an external API using the HttpClient library and
- see responses within the editor, or use workers to do them in the
- background. Use the built-in package manager to make external API
- calls really easily, and contribute your own API integrations.
-
-
-
-
-
- CRUD apps
-
-
- Get a working CRUD application in less than ten minutes by setting
- up a few API endpoints and a datastore. Build out the backend for a
- web or mobile app, whether a simple HTML form or an entire product.
-
-
-
-
-
-
-
- Dark lets you build any backend that needs API endpoints, data stores,
- background workers, scheduled jobs, and calling HTTP APIs. You just
- write the code in Dark, and we'll manage the rest.
-
- 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,
- just
- code.
-
-
-
- ๏ธ๏ธ๏ธ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 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 language
-
-
- Simple 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.functionName
- arg1
- arg2
-
-
-
-
- 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.
-
-
-
-
-
- No
- async /
- 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
- deployment
-
- Optional
-
- 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
-
- darklang
- prompt "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
- .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ Cannot use List without completing the method call
+
+
+
+ )}
+
+ {/* Go to definition - Popup with function definition */}
+ {showGoToDef && (
+ <>
+ {/* Underline the function name */}
+
+
+ {/* Small popup showing function definition */}
+
+
+ packages for integrating with OpenAI or other models
+
+
+
+
+
support for local whatever
+
+
+
+
+
+
+ {/* User-Facing Features */}
+
+
+ AI for Your Users
+
+
+
+
+
+
"built for AI"
+
+
+
+
build vendor SDKs automagically
+
+
+
+
prompt using your AI, or ours
+
+
+
+
build AI models in darklang
+
+
+
+
agents
+
+
+
+
+
+ {/* Advanced Features Grid */}
+
+ {/* Future Features */}
+
+
+ Future Capabilities
+
+
+
+
+
+ future: native support for vector DBs?
+
+
+
+
+
+ {/* LangChain Alternative */}
+
+
+ LangChain Alternative
+
+
+
+
+
alternative to langchain
+
+
+
+
prompt pipelines, etc
+
+
+
+
+
+ {/* GenAI Features */}
+
+
+ Designed for GenAI
+
+
+
(bullets from "designed for GenAI")
+
+ Darklang provides a comprehensive platform for building,
+ deploying, and managing AI-powered applications with built-in
+ support for modern generative AI workflows and tools.
+
+ talk about features http handlers CRONs workers etc. talk about our
+ cloud offerings reference things in dark-classic talk about eventual
+ migration from -classic to -next
+
+
+
+ {/* Introduction */}
+
+
+
+ Darklang is a programming language and platform designed to
+ simplify backend development by removing much of the complexity
+ associated with traditional backend infrastructure. Its backend
+ features are tightly integrated into a single environment, and
+ built to streamline the creation of cloud-native applications
+ without managing infrastructure, deployments, or containers.
+
+
+
+ Darklang's backend featuresโHTTP handlers, scheduled jobs (CRONs),
+ background workers, and datastores are designed for rapid
+ development and prototyping, with a focus on simplicity and
+ instant deployment.
+
+
+
+
+ {/* Main Features Grid */}
+
+ {/* Datastores */}
+
+
Datastores
+
+
+
+
+ Datastores in Darklang are key-value stores used for
+ persistent data storage, integrated seamlessly with handlers
+ and workers.
+
+
+
+
+
+ when you set up a database in dark, you just add the database,
+ like you click a button or a keyboard shortcut, no requiring a
+ server from somewhere to put it on, no going to another
+ server, no config, no orm it is written in the same language
+ as the rest of your code
+
+
+
+
+
+ when you make a query, you query in the dark
+
+
+
+
+
+ {/* HTTP Handlers */}
+
+
+ HTTP Handlers
+
+
+
+
+
+ HTTP handlers in Darklang are the core mechanism for handling
+ incoming HTTP requests, serving as the entry point for API
+ endpoints and web applications.
+
+
+
+
+
+ when setting up a HTTP request you're not setting up a HTTP
+ server, you're just add an end point that is directly
+ connected to the code and you write them in the same place.
+ There's no spinning up servers
+
+
+
+
+
+ Darklang is designed for interacting with 3rd party APIs over
+ HTTP. The `HttpClient` module has a set of functions for
+ calling out to other HTTP services and APIs
+
+
+
+
+
+ {/* Scheduled Jobs */}
+
+
Scheduled Jobs
+
+
+
+
+ CRON jobs in Darklang are scheduled tasks that run on a
+ predefined schedule, similar to Unix cron, ideal for periodic
+ tasks like report generation or data cleanup.
+
+
+
+
+
+ Crons run automatically once per interval
+
+
+
+
+
+ {/* Background Workers */}
+
+
+ Background Workers
+
+
+
+
+
+ Workers in Darklang handle asynchronous background tasks,
+ processing messages from a queue, making them ideal for tasks
+ like API calls, batch processing, or report generation.
+
+
+
+
+
+
+ {/* Database Operations */}
+
+
+ Database Operations
+
+
+
talk about operations?
+
+
+
+
- (DB.set, DB.get...)
+
+
+
+
- (DB.query...)
+
+
+
+
+
+ {/* Worker Implementation */}
+
+
+ Worker Implementation Details
+
+
+
+ Darklang supports doing work asynchronously outside the context of
+ an HTTP handler using a **Worker**. Each worker has a queue of
+ messages, which are processed loosely in-order, executing the code
+ within the Worker once for each message. Messages are created by
+ calling `emit` from any other code, and can contain arbitrary
+ event data.
+
+
ADD Example use case?
+
+
+
+
+ );
+};
+
+export default Backends;
diff --git a/src/pages/CLI/index.tsx b/src/pages/CLI/index.tsx
new file mode 100644
index 0000000..4dee2b7
--- /dev/null
+++ b/src/pages/CLI/index.tsx
@@ -0,0 +1,399 @@
+import React from "react";
+
+import cliImage from "~/assets/cli.png";
+import doubleGridImage from "~/assets/double-grid.png";
+import gridImage from "~/assets/grid.png";
+import logoAscii from "~/assets/logo-ascii.png";
+import cliAscii from "~/assets/darklang-cli-ascii.png";
+
+import Terminal from "../../common/ui/Terminal.tsx";
+// import Button from "../../common/ui/Button.tsx";
+// import CTASection from "../../common/ui/CTASection/index.tsx";
+
+const CLIPage: React.FC = () => {
+ return (
+
+ {/* ASCII Art Header Section - Hidden on Mobile */}
+
+
+
+
+
+
+ {/* CLI Platform Section */}
+
+
+
+
+ $ darklang platform |
+
+
+ Darklang's CLI is fully cross-platform, seamlessly running on
+ macOS, Linux, and Windows for a consistent development experience
+ everywhere
+
+ {/* */}
+
+
+
+
+
+
+
+ {/* Get Started Section */}
+ {/*
+
+ $ darklang get started |
+
+ */}
+
+ {/* Bash Complexities Section */}
+
+
+ $ darklang as an alternative to bash, python, etc. |
+
+
+
+
+
+ Darklang CLI is a better replacement for traditional file-based
+ scripts, such as in bash, python, lua, js, etc.
+
+
+
+ bash is super hard to read, using weird variable names. While lots
+ of us can read and write bash scripts, since there are few
+ experts, it's not a great language.
+
+
+
+
+ -
+
+ lack of a package manager means the generated code has to use
+ cli tools, which each have different interfaces, which may not
+ be installed, and are often opaque
+
+
+
+
+ -
+
+ different versions of the tools might be installed with subtly
+ different behaviour (esp gnu vs bsd)
+
+
+
+
+ -
+
+ lack of real types and functions (which are a mess in bash)
+ contributes to these problems
+
+
+
+
+
+ Python scripts can be just as messy as bash, often requiring you
+ to spin up virtual environments for every project just to avoid
+ dependency conflicts
+
+
+
+
+
+
+
+
+ {/* Darklang for Scripts Section */}
+
+
+ $ darklang is a better lanuage for your scripts |
+
+
+
+
+
+
+ -
+
+ Static types help ensure correctness
+
+
+
+
+ -
+
+ Immutable values make code easier to understand and verify
+
+
+ Run a function in the package manager i.e. `dark
+ @Darklang.Stdlib.Bool.not true`
+
+
+
+
+
+ dark run [script path]
+
+
+ Run a .dark script i.e. `dark ./my-script.dark`
+
+
+
+
+
+ dark install
+
+
+ Install the darklang CLI so it's available globally in your
+ terminal
+
+
+
+
+
+ dark http
+
+
+ Lists both local and cloud handlers
+
+
+
+
+
+ dark dbs
+
+
+ Lists both local and cloud dbs
+
+
+
+
+ {/*
+
+
*/}
+
+
+ {/*
+
+
+ Getting Started with Darklang CLI
+
+
+ Write your first script in Darklang today and have it running in
+ minutes
+
+
+
+ */}
+
+ );
+};
+
+export default CLIPage;
diff --git a/src/pages/Classic/index.tsx b/src/pages/Classic/index.tsx
new file mode 100644
index 0000000..84dd53a
--- /dev/null
+++ b/src/pages/Classic/index.tsx
@@ -0,0 +1,197 @@
+import darklangClassic from "~/assets/darklang-classic.png";
+import darkClassicToplevel from "~/assets/dark-classic-toplevel.png";
+
+// TODO talk about how things will eventually be migrated to "-next"
+
+const About = () => {
+ return (
+
+
+ {/* Logo section */}
+
+
+
+
+ {/* Main content - First Section */}
+
+
+ Dark
+
+ {" "}
+ is a new way of building serverless backends. Just code your
+ backend, with no infra, framework or deployment nightmares.
+ Build{" "}
+
+ APIs
+ ,
+ CRUD
+ apps,
+ internal tools
+ and
+ bots
+ - whatever your backend needs.
+
+
+
+ Sign ups for Darklang Classic are no longer available. It had been
+ running in production since 2019, and we've decided to{" "}
+
+ wind it down
+
+ . Darklang-next is the next iteration of Dark, applicable to both
+ the cloud runtime and to local scripts and CLIs.
+
+
+
+ {/* Code Editor Image Section */}
+
+
+
+
+ {/* Key Capabilities */}
+
+
+ {/* Internal Tools & Bots */}
+
+
+ Internal Tools
+ &
+ Bots
+
+
+ Dark is ideal for quickly building slackbots and automating
+ internal tools. Receive webhooks live, call out to 3rd party
+ APIs, store data, and schedule jobs - while building no
+ infrastructure.
+
+ Set up an API endpoint quickly enough to use it as a proof of
+ concept during a call. Immediately see the data from a webhook
+ to your endpoint. Call an external API using the HttpClient
+ library and see responses within the editor, or use workers to
+ do them in the background. Use the built-in package manager to
+ make external API calls really easily, and contribute your own
+ API integrations.
+
+
+
+ {/* CRUD apps */}
+
+
+ CRUD
+ apps
+
+
+ Get a working CRUD application in less than ten minutes by
+ setting up a few API endpoints and a datastore. Build out the
+ backend for a web or mobile app, whether a simple HTML form or
+ an entire product.
+
+
+
+
+
+ {/* Any Backend Section */}
+
+
+ Any
+ Backend
+ That Requires...
+
+
+
+ {/* Feature Card 1 */}
+
+
+ API
+ Endpoints
+
+
+
+ {/* Feature Card 2 */}
+
+
+ Data
+ Stores
+
+
+
+ {/* Feature Card 3 */}
+
+
+ Background
+ Workers
+
+
+
+ {/* Feature Card 4 */}
+
+
+ Scheduled
+ Jobs
+
+
+
+
+
+ Dark lets you build any backend that needs API endpoints, data
+ stores, background workers, scheduled jobs, and calling HTTP APIs.
+ You just write the code in Dark, and we'll manage the rest.
+
+ Darklang has been around in various form since xxxxxx. ## Vision ##
+ Mission ## Funding, Sustainability, Licensing, and Business Model In order
+ to work on our mission, towards our vision, we must be sustainable.
+ [sponsor, licensing] (if you're interested in giving us $, ...) ##
+ Branding (link to another page) ## Roadmap - [...] ## Are we hiring? No,
+ sorry, not currently. We're limited on funding. ## History ... Licensing
+ Cloud hosting plz give us money burndown chart?
+
+ package management source control building artifacts for end users
+
+
+
+ {/* Main Content Section */}
+
+
+
+ TODO: move this somewhere else
+
+ Darklang is a cloud-native programming language and platform
+ designed to simplify the development of serverless backends by
+ introducing a "deployless" model. This approach aims to remove the
+ complexities of traditional software deployment, allowing developers
+ to focus on writing code rather than managing infrastructure,
+ builds, or deployment pipelines.
+
+
+
+ In traditional software development, deploying code involves
+ multiple steps: writing code, committing it to a repository (e.g.,
+ via Git), creating pull requests, building assets, pushing
+ containers to registries, and orchestrating deployments (e.g., via
+ Kubernetes). Darklang eliminates roughly 60% of these steps by
+ integrating the language, editor, and infrastructure into a cohesive
+ platform. The result is a deployment process that takes
+ approximately 50 milliseconds, enabling rapid iteration and testing
+ in production.
+
+
+
+ The deployless model is analogous to serverless computing: just as
+ serverless abstracts away server management, deployless abstracts
+ away deployment management so that you don't have to think about it
+
+
+
+ Developers don't need to configure build systems, containers,
+ Kubernetes, or CI/CD pipelines. The platform handles scaling,
+ monitoring, and optimization
+
+
+
+ Feature flags allow developers to test code in production without
+ exposing it to users, and precise access controls enhance security
+
+
+
+ No Infrastructure Management: Developers avoid configuring servers,
+ databases, or networking components.
+
+
+
+ Developers spend less time on DevOps tasks, focusing on application
+ logic
+
+
+
+
+ );
+};
+
+export default Distribution;
diff --git a/src/pages/Editing/index.tsx b/src/pages/Editing/index.tsx
new file mode 100644
index 0000000..53b5aa9
--- /dev/null
+++ b/src/pages/Editing/index.tsx
@@ -0,0 +1,215 @@
+import React from "react";
+
+import doubleGridSquare from "~/assets/double-grid-square.png";
+import darklangLogoFramed from "~/assets/darklang-logo-framed.png";
+
+// import Button from "../../common/ui/Button";
+import CodeEditor from "../../common/ui/CodeEditor";
+// import CTASection from "../../common/ui/CTASection";
+
+const Editing: React.FC = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Multi-Editor Support
+
+ Darklang's language server is designed to work across multiple
+ editing environments, providing a consistent experience
+ regardless of your preferred editor.
+
+ {/*
+
+
+
*/}
+
+
+
+
+
+ {/* LSP Server Section */}
+
+
Darklang LSP Server
+
+
+ Our language server is fully written in Darklang and follows the
+ Language Server Protocol (LSP), providing features like
+ autocompletion, real-time error checking, and hover documentation. It
+ is currently integrated with a lightweight VS Code extension, and we
+ plan to support more editors like Vim, Rider, and Sublime in the
+ future.
+
+ Many of our language tools are fully accessible to users. Just like
+ forking and editing your own code, you can fork the language server
+ to change how features like onHover, autocompletion, or diagnostics
+ work.
+
+
+
+ It's also easy to create your own language servers, whether for
+ testing new ideas or developing specialized tools, building internal
+ Darklang features, or your own independent projects.
+
+
+
+
+ {/* Extension Section */}
+
+
VSCode Extension
+
+
+
+ We are currently focused on building a VS Code extension because of
+ its rich API ecosystem and powerful FileSystemProvider (FSP)
+ capabilities. Unlike traditional development where code exists as
+ plain text files on disk, Darklang's code is stored in a package
+ manager, making VS Code's FSP particularly valuable for our
+ implementation.
+
+
+
+
+
+
+ Future Editor Support
+
+
+
+
+ While VS Code is our starting point, we're actively planning support
+ for additional editors including Vim, Sublime Text, and Rider, as
+ well as enabling a fully integrated AI-powered terminal-based
+ editing experience.
+
+ I'm thinking to have a bunch of pages like darklang.com/for/web-developers
+ with dedicated content for groups of folks who we think might appreciate
+ Darklang. here are some ideas darklang.com/for/fsharp-developers
+ darklang.com/for/home-automation darklang.com/for/eInk-devices
+ darklang.com/for/web-developers darklang.com/for/people-with-money (letter
+ asking them to invest etc?) darklang.com/for/people-who-want-money
+ (entrepreneurs? scripters? people with servers?)
+ darklang.com/for/security-nerds darklang.com/for/unix-users
+ darklang.com/for/accessibility darklang.com/for/AI-developers
+ darklang.com/for/lazy-people darklang.com/for/folks-who-collect-domains
+ darklang.com/for/python-developers darklang.com/for/web-scrapers (the web
+ is ridden with flies, you can hardly see through. scrape the web and
+ provide) also good for folks who are into those browser extensions...
+ something monkey? that remove ads and such darklang.com/for/privacy
+ darklang.com/for/local-first darklang.com/for/small-businesses (SSG;
+ wordpress alt.; affordable software solutions and contracting) in each of
+ these, include expandable section for context for those outside the know
+
+ 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.
+
+ 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.
+
+ );
+};
+
+// Code examples for each feature
+const codeExamples = {
+ httpHandlerGET: `[]
+let _handler _req =
+ let products = Stdlib.DB.getAll ProductsDB
+
+ let body =
+ products
+ |> Builtin.jsonSerialize
+ |> Stdlib.String.toBytes
+
+ Stdlib.Http.responseWithHeaders
+ body
+ 200L
+ [("Content-Type", "application/json")]`,
+
+ httpHandlerPOST: `[]
+let _handler req =
+ // Parse the request body
+ let body =
+ req.body
+ |> Stdlib.String.fromBytes
+ |> Builtin.jsonDeserialize<{
+ name: String
+ price: Float
+ description: String
+ category: String
+ }>
+
+ // Create a new product
+ let newProduct = {
+ id = Stdlib.Uuid.generate()
+ name = body.name
+ price = body.price
+ description = body.description
+ category = body.category
+ createdAt = Stdlib.Date.now()
+ indexed = false
+ }
+
+ // Save to database using the UUID as key
+ Stdlib.DB.set newProduct newProduct.id ProductsDB
+
+ // Emit product to background worker
+ emit { productId = newProduct.id } "product-indexer"
+
+ // Return the created product
+ let responseBody =
+ newProduct
+ |> Builtin.jsonSerialize
+ |> Stdlib.String.toBytes
+
+ Stdlib.Http.responseWithHeaders
+ responseBody
+ 201L
+ [("Content-Type", "application/json")]`,
+
+ httpHandlerDELETE: `[]
+let _handler req =
+ let productId = req.pathParams["id"] |> Stdlib.Uuid.parse |> Builtin.unwrap
+
+ match Stdlib.DB.get productId ProductsDB with
+ | Some product ->
+ Stdlib.DB.delete productId ProductsDB
+
+ Builtin.printline $"Product {productId} deleted"
+
+ Stdlib.Http.response
+ (Stdlib.String.toBytes "")
+ 204L
+
+ | None ->
+ // Product not found
+ Stdlib.Http.responseWithHeaders
+ Stdlib.String.toBytes "Product not found"
+ 404L
+ [("Content-Type", "application/json")]`,
+
+ dataStores: `// Define our product type
+type Product = {
+ id: Stdlib.Uuid.UUID
+ name: String
+ price: Float
+ description: String
+ category: String
+ createdAt: Date
+ indexed: Bool
+}
+
+// Create the database
+[]
+type ProductsDB = Product`,
+
+ scheduledJobs: `[]
+let _handler () =
+ // Count total products
+ let products = Stdlib.DB.getAll ProductsDB
+ let totalProducts = Stdlib.List.length products
+
+ // Send email report
+ Stdlib.Email.send {
+ to = "admin@example.com"
+ subject = "Daily Product Report"
+ body = $"Total Products: {totalProducts}"
+ }
+
+ Builtin.log "Daily report sent successfully"`,
+
+ backgroundWorkers: `// Define a worker to process products asynchronously
+[]
+let _handler =
+ // Access the event data (comes from emit)
+ let productId = event.productId
+
+ // Get the product from database
+ match Stdlib.DB.get productId ProductsDB with
+ | Some product ->
+ // Log start of processing
+ Builtin.log $"Processing product {product.id}: {product.name}"
+
+ // Update the product status
+ let updatedProduct = { product with indexed = true }
+ Stdlib.DB.set updatedProduct product.id ProductsDB
+
+ // Log completion
+ Builtin.log $"Product {product.id} marked as indexed"
+
+ | None ->
+ Builtin.log $"Product {productId} not found"
+`,
+};
+
+const BackendFeatures: React.FC = () => {
+ const [selectedFeature, setSelectedFeature] =
+ useState("httpHandlerGET");
+
+ // HTTP handler dropdown options
+ const httpHandlerOptions = [
+ { label: "GET /products", value: "httpHandlerGET" },
+ { label: "POST /products", value: "httpHandlerPOST" },
+ { label: "DELETE /products/:id", value: "httpHandlerDELETE" },
+ ];
+
+ // Get the code for the currently selected feature
+ const currentCode = codeExamples[selectedFeature];
+
+ return (
+
+
+
+
+ Build a complete backend with Darklang
+
+
+
+ Darklang lets you easily develop backend applications, seamlessly
+ deployable to the cloud. You can build tiny applications to connect
+ two services, or large scale applications with tens of thousands of
+ users. Code is written in collaboration with AI and is instantly and
+ safely deployed on our hosted platform or yours, so you can focus on
+ writing code while we handle the rest
+
+
+ );
+};
+
+export default BlogPosts;
diff --git a/src/pages/Home/BlogPostsExample.tsx b/src/pages/Home/BlogPostsExample.tsx
new file mode 100644
index 0000000..054261e
--- /dev/null
+++ b/src/pages/Home/BlogPostsExample.tsx
@@ -0,0 +1,45 @@
+import React from "react";
+
+import BlogPosts from "./BlogPosts";
+
+// Mock data for blog posts
+const mockPosts = [
+ {
+ id: "1",
+ author: "Stachu Korick",
+ date: "16 Jun 2025",
+ title: "First Steps of Darklang Inc.",
+ excerpt:
+ "Darklang Inc is the new steward of the Darklang language, whose team has been working on Darklang for several years. In this post, we'll cover three big changes...",
+ imageUrl:
+ "src/assets/Cole_Thomas_The_Oxbow_-The_Connecticut_River_near_Northampton_1836-.jpeg",
+ slug: "https://blog.darklang.com/first-steps-of-darklang-inc/",
+ },
+ {
+ id: "2",
+ author: "Paul Biggar",
+ date: "16 Jun 2025",
+ title: "Goodbye Dark Inc. - Hello Darklang Inc.",
+ excerpt:
+ "Dark Inc has officially run out of money. Dark Inc is the company we founded in 2017 to build Darklang...",
+ imageUrl: "src/assets/Velazquez-The_Surrender_of_Breda.jpeg",
+ slug: "https://blog.darklang.com/goodbye-dark-inc-welcome-darklang-inc/",
+ },
+ {
+ id: "3",
+ author: "Stachu Korick",
+ date: "16 Jun 2025",
+ title: "Darklang Goes Open Source",
+ excerpt:
+ "As part of shutting down Dark Inc. and forming Darklang Inc., we've finally open-sourced all of our repositories. Our source code is now under the Apache License 2.0....",
+ imageUrl:
+ "src/assets/The_School_of_Athens__by_Raffaello_Sanzio_da_Urbino.jpeg",
+ slug: "https://blog.darklang.com/darklang-goes-open-source/",
+ },
+];
+
+export const BlogPostsExample: React.FC = () => {
+ return ;
+};
+
+export default BlogPostsExample;
diff --git a/src/pages/Home/CLI.tsx b/src/pages/Home/CLI.tsx
new file mode 100644
index 0000000..f20a341
--- /dev/null
+++ b/src/pages/Home/CLI.tsx
@@ -0,0 +1,157 @@
+import React from "react";
+
+import cliImage from "~/assets/cli.png";
+
+import SectionTitle from "../../common/ui/SectionTitle";
+
+const CLI: React.FC = () => {
+ return (
+
+
+
+ {" "}
+ A CLI Runtime to Replace your Bash and Python Scripts
+
+
+
+ {/* Left side - Text content */}
+
+
+
+
+
+
+ Darklang's CLI is a better alternative to Bash, combining its
+ power with the simplicity and safety of modern programming
+ languages. Enabling you to write scripts without confusing
+ errors or dependency issues.
+
+ }
+ title="Write code and it's immediately available"
+ description="No build step, no wait time, no deployment pipeline your code is live as soon as you type."
+ />
+
+ }
+ title="Feature flags for controlled rollouts"
+ description="Control exactly when and for whom new features go live. Test in production safely with instant rollback capability"
+ />
+
+ }
+ title="Development/Production Parity"
+ description="Your development environment matches the production environment, so you can test with confidence."
+ />
+
+ }
+ title="Integrated code review and testing"
+ description="Review code, run tests, and collaborate seamlessly in one place"
+ />
+
+
+
+
+ Zero setup infrastructure
+
+ }
+ title="Instant infrastructure creation"
+ description="Language-native HTTP handlers, Databases, CRONs and queues, without thinking about servers, containers, or deployment"
+ />
+
+ }
+ title="Simplified Architecture"
+ description="No need to worry about connection poolers, sharding, indexes, load balancers, cloud services, or system administrationโeverything runs seamlessly in the background"
+ />
+
+
+ );
+};
+
+export default DevelopmentSteps;
diff --git a/src/pages/Home/Editing.tsx b/src/pages/Home/Editing.tsx
new file mode 100644
index 0000000..841a5cc
--- /dev/null
+++ b/src/pages/Home/Editing.tsx
@@ -0,0 +1,88 @@
+import React from "react";
+import editingImg from "~/assets/editing3.png";
+import SectionTitle from "../../common/ui/SectionTitle";
+const Editing: React.FC = () => {
+ const features = [
+ {
+ id: 1,
+ description:
+ "Darklang has a Language Server that provides real-time feedback, AI-powered completions, instant diagnostics, and easy access to language features. The server communicates through a lightweight VS Code extension enabling seamless integration and an intuitive experience.",
+ },
+ {
+ id: 2,
+ description:
+ "Built entirely in Darklang, the language server follows the Language Server Protocol (LSP), making it easy to expand support to more editors so you can use Darklang in your favourite development environment.",
+ },
+ {
+ id: 3,
+ description:
+ "The Language Server is designed to be adjustable and expandable, allowing users to configure it to fit their needs.",
+ },
+ ];
+ return (
+
+
+
+
+
+
+ Powerful, Familiar, and Extensible editing
+
+
+ Edit code in your preferred environmentโwhether it's your local
+ editor, a browser-based IDE, or directly in the CLI. This is
+ made possible by Darklang's Language Server:
+
+
+ );
+};
+export default Editing;
diff --git a/src/pages/Home/GradualStaticTyping.tsx b/src/pages/Home/GradualStaticTyping.tsx
new file mode 100644
index 0000000..eed0b59
--- /dev/null
+++ b/src/pages/Home/GradualStaticTyping.tsx
@@ -0,0 +1,73 @@
+import React from "react";
+
+import SectionTitle from "../../common/ui/SectionTitle";
+
+type FeaturePoint = {
+ text: string | React.ReactNode;
+};
+
+const GradualStaticTyping: React.FC = () => {
+ const featurePoints: FeaturePoint[] = [
+ { text: "While prototyping, just run code until you hit a type error" },
+ {
+ text: "After prototyping, run the full type checker to gain confidence your whole program works",
+ },
+ {
+ text: (
+ <>
+ ! and{" "}
+ ? operators allow easy
+ error handling while you prototype
+ >
+ ),
+ },
+ {
+ text: (
+ <>
+ Automatic refactoring converts{" "}
+ ! into proper error
+ handling
+ >
+ ),
+ },
+ { text: "Full type-checking hints in VSCode or in LSP editors" },
+ ];
+
+ return (
+
+
+
+ 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
+
+);
+
+// Main Component
+const LanguageFeatures: React.FC = () => {
+ // Tab data
+ const tabs: TabData[] = [
+ {
+ id: "functional",
+ label: "Functional Style",
+ code: `// Simple types
+type UserAction =
+ | Click of String
+ | Type of String
+ | Submit
+
+// Match patterns
+let handleAction (action:UserAction) : String =
+ match action with
+ | Click button -> $"Button '{button}' clicked."
+ | Type input -> $"User typed: '{input}'"
+ | Submit -> "Form submitted!"
+
+let actions = [Click "Login"; Type "Hello"; Submit]
+
+// First-class functions
+let logs = actions |> Stdlib.List.map handleAction
+
+// Immutable and composable
+logs |> List.iter printLine`,
+ },
+ {
+ id: "records",
+ label: "Records & Enums",
+ code: `// Record
+type Url = {
+ scheme : HttpScheme
+ domain : String
+ port : UInt16
+ path : String
+ query : Option
+}
+
+// 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`,
+ },
+ {
+ id: "option",
+ label: "Option & Result types",
+ code: `// Option type instead of null
+type Option<'v> =
+| Some of 'v
+| None
+
+let findUser (users: List) (id: int) : Option =
+ users |> List.tryFind (fun user โ user.Id = id)
+
+// Result type instead of exceptions
+type Result<'Ok, 'Err> =
+| Ok of 'Ok
+| Error of 'Err
+
+let findUser
+(users: List)
+(id: int)
+: Result =
+ let user = users |> List.tryFind (fun user โ user.Id = id)
+ match user with
+ | Some user โ Ok user
+ | None โ Error NotFound`,
+ },
+ {
+ id: "unicode",
+ label: "Unicode-First",
+ code: `// All characters in Darklang represent Extended Grapheme
+// Clusters.
+
+// Characters represent what you see on screen
+String.length "hello" // 5
+String.length "๐จโ๐ฉโ๐งโ๐ฆ" // 1`,
+ },
+ ];
+
+ const features = [
+ "Built-in immutability and strong type system",
+ "Garbage-collected",
+ "Records and Enums for straightforward data modeling",
+ "Option and Result types keep errors explicit",
+ "Unicode-first",
+ ];
+
+ const [activeTab, setActiveTab] = useState(tabs[0].id);
+
+ // Get current tab code
+ const getCurrentTabCode = () => {
+ const tab = tabs.find(tab => tab.id === activeTab);
+ return tab ? tab.code : "";
+ };
+
+ return (
+
+
+
+ {/* Left side */}
+
+
+ Functional, Composable, and Fun to use
+
+
+
+ Darklang is a statically-typed functional language built for
+ simplicity and composability. No null, no unexpected exceptions
+ โjust predictable code that's easy to write, read, and maintain.
+
+ Get notified about new features, updates, Bug Fixes, project
+ milestones, and more
+
+
+
+ {!isSubmitted ? (
+
+ ) : (
+
+ Added to waitlist!
+
+
+ )}
+
+
+
+ );
+};
+
+export default Newsletter;
diff --git a/src/pages/Home/PackageManager.tsx b/src/pages/Home/PackageManager.tsx
new file mode 100644
index 0000000..4b4306b
--- /dev/null
+++ b/src/pages/Home/PackageManager.tsx
@@ -0,0 +1,127 @@
+import React from "react";
+
+import packageManagerImg from "~/assets/packageManager.png";
+
+import SectionTitle from "../../common/ui/SectionTitle";
+
+const PackageManager: React.FC = () => {
+ const features = [
+ {
+ id: 1,
+ title: "No Install Step",
+ description:
+ "Built-in package management without npm-style installation processes or Python's painful package compatibility issues.",
+ },
+ {
+ id: 2,
+ title: "Immutable",
+ description:
+ "Updates never overwrite existing code but create new versions with unique identifiers.",
+ },
+ {
+ id: 3,
+ title: "No More Downloading the Internet",
+ description:
+ "Only download and upgrade the specific package items you use.",
+ },
+ {
+ id: 4,
+ title: "Source-Controlled Package Management",
+ description: "The package manager functions as a source repository.",
+ },
+ {
+ id: 5,
+ title: "Smart Dependency Management",
+ description:
+ "Automated dependency upgrades, as we track deprecation status, and know what functions are pure and safe to update.",
+ },
+ {
+ id: 6,
+ title: "Version Flexibility",
+ description:
+ "Different packages can rely on different versions of other packages.",
+ },
+ {
+ id: 7,
+ title: "Parallel Versioning",
+ description:
+ "Use multiple versions of the same package item at once: allows testing new versions without having to change an entire package version, lowering risk.",
+ },
+ {
+ id: 8,
+ title: "Effortless Pre-Release Sharing",
+ description:
+ "Share pre-release functions trivially, without contributors needing to check out your git repo or set up anything.",
+ },
+ {
+ id: 9,
+ title: "Zero Overhead Workflow",
+ description:
+ "No need for uploads, releases or other synchronization. No git or GitHub required (but you can sync to GitHub if you prefer).",
+ },
+ ];
+
+ return (
+
+
+
+ Next-gen Package Manager
+
+
+
+ Darklang has a rather unique package manager built directly into the
+ runtime, where functions and types are individually versioned and
+ immutable, taking a lot of the hassle out of package management.
+
+ The best way to debug and refactor code is with the help of{" "}
+ real user data. As your
+ code executes, whether{" "}
+ locally or in the{" "}
+ cloud, traces are
+ captured and made available in your development workflow, making
+ it easier to refactor code and debug issues.
+
+
+
+ Traces are captured centrally in the package manager, stored
+ locally first, and securely available in your editing environment
+ - you control when and if they sync.
+
+ }
+ description="Capture and analyze HTTP requests and responses in real-time. Debug API integrations with complete request data."
+ traceData={httpTraceData}
+ color="blue"
+ >
+
+ }
+ description="Inspect function inputs, outputs, and performance metrics. Debug complex operations with detailed traces."
+ traceData={fnCallTraceData}
+ color="magenta"
+ >
+
+ }
+ description="Track CLI operations with detailed input and output records. Monitor script execution, environment variables, and command results for easy debugging."
+ traceData={cliTraceData}
+ color="purple"
+ >
+
+
+ {/* Right column of cards */}
+
+ }
+ description="Track and monitor background workers and their execution. Observe task processing in real-time."
+ traceData={workerTraceData}
+ color="taupe"
+ >
+
+ }
+ description="Monitor scheduled tasks and their execution results. Ensure automation runs correctly with real data."
+ traceData={cronTraceData}
+ color="orange"
+ >
+
+ }
+ description="Customize your own trace types and visualizations. Monitor any aspect of your application with flexible data collection."
+ traceData={miscTraceData}
+ color="gray"
+ >
+
+
+
+
+
+
+ );
+};
+
+export default TraceDrivenDevelopment;
diff --git a/src/pages/Home/index.tsx b/src/pages/Home/index.tsx
new file mode 100644
index 0000000..0db9f2d
--- /dev/null
+++ b/src/pages/Home/index.tsx
@@ -0,0 +1,91 @@
+import Hero from "./Hero";
+import DevelopmentSteps from "./DevelopmentSteps";
+import BackendFeatures from "./BackendFeatures";
+import LanguageFeatures from "./LanguageFeatures";
+import AsyncRuntime from "./AsyncRuntime";
+import GradualStaticTyping from "./GradualStaticTyping";
+import PackageManager from "./PackageManager";
+import TraceDrivenDevelopment from "./TraceDrivenDevelopment";
+import Editing from "./Editing";
+import CLI from "./CLI";
+import DeploylessCloud from "./DeploylessCloud";
+import DesignedForGenAI from "./DesignedForGenAI";
+import Newsletter from "./Newsletter";
+import BlogPostsExample from "./BlogPostsExample";
+import { TableOfContents } from "../../components";
+
+const Home = () => {
+ // Table of contents items
+ const tocItems = [
+ { id: "hero", title: "Build above the cloud" },
+ { id: "development-steps", title: "Get started in no time" },
+ {
+ id: "language-features",
+ title: "Functional, Composable, and Fun to use",
+ },
+ { id: "async-runtime", title: "Async Runtime" },
+ { id: "static-typing", title: "Gradual Static Typing" },
+ { id: "package-manager", title: "Next-gen Package Manager" },
+ { id: "trace-driven", title: "Development with Real Data" },
+ { id: "editing", title: "Powerful, Familiar, and Extensible editing" },
+ { id: "backend-features", title: "Build a complete backend with Darklang" },
+ {
+ id: "cli",
+ title: "A CLI Runtime to Replace your Bash and Python Scripts",
+ },
+ { id: "deployless-cloud", title: "Deployless, Infraless Cloud Apps" },
+ { id: "designed-for-ai", title: "Designed for Generative AI" },
+ { id: "newsletter", title: "Send me project updates" },
+ { id: "blog-posts", title: "Recent Blog Posts" },
+ ];
+
+ return (
+ <>
+
+
+ Darklang is a statically-typed, functional/imperative hybrid
+ programming language designed primarily for building cloud-based
+ backend services. Its functional aspects draw inspiration from
+ languages like OCaml, Elm, and Rust, emphasizing simplicity, type
+ safety, and productivity while avoiding complex functional programming
+ concepts like monads or category theory.
+
+
+
+ {/* Core Features */}
+
+
Core Features
+
+ {/* Immutability */}
+
+
+ Immutability
+
+
+ Darklang embraces immutability, a core functional programming
+ principle. Values in Darklang are immutable by default, eliminating
+ race conditions in concurrent execution and making programs easier
+ to reason about.
+
+
+
+ {/* Error Handling */}
+
+
+ No Exceptions, Use of Results and Options
+
+
+ Instead of exceptions, which can complicate reasoning in functional
+ programming, Darklang uses Result and Option types to handle errors
+ and optional values. This approach, inspired by languages like Rust
+ and OCaml, ensures explicit error handling and avoids issues
+ associated with nulls or unchecked exceptions.
+
+
+
+ {/* Functions and Pipelines */}
+
+
+ First-Class Functions and Pipelines
+
+
+ Darklang supports first-class functions, enabling functions to be
+ passed as arguments, returned from other functions, and assigned to
+ variables, a standard feature in functional languages. It makes
+ heavy use of pipelines (similar to F# or Elm), allowing developers
+ to chain function calls in a readable, declarative way. For example,
+ operations like List::map are used to transform collections
+ functionally.
+
+
+
+ {/* Implicit Returns */}
+
+
+ Implicit Returns
+
+
+ Like many functional languages (e.g., Elm or Haskell), Darklang uses
+ implicit returns, where the last expression in a function is
+ automatically its return value. This reduces boilerplate and aligns
+ with functional programming's focus on expressions over statements.
+
+
+
+ {/* Type System */}
+
+
+ Simple Type System with Records and Enums
+
+
+ Darklang employs a straightforward type system based on Records and
+ Enums (also known as variants or sum types), similar to Rust, Elm,
+ or OCaml. These types are expressive enough to model complex data
+ structures while remaining simpler than object-oriented class
+ hierarchies. For example, a Url type might be defined as a record
+ with fields like scheme, domain, and port, while a UrlError enum
+ could represent possible errors like InvalidScheme or EmptyDomain.
+ This approach avoids the complexity of inheritance and aligns with
+ functional programming's preference for algebraic data types.
+
+
+
+ {/* Hybrid Nature */}
+
+
+ Functional/Imperative Hybrid
+
+
+ While primarily functional, Darklang is described as a
+ functional/imperative hybrid, drawing from OCaml, Elm, and Rust
+ rather than purely functional languages like Haskell. This hybrid
+ nature makes it accessible to developers familiar with imperative or
+ object-oriented languages, avoiding esoteric functional concepts
+ like monads, lenses, or combinators. The language prioritizes
+ developer productivity by allowing imperative-style code where
+ needed, but its functional core ensures type safety and
+ immutability.
+
+
+
+ {/* Async Programming */}
+
+
+ Asynchronous Programming Without await
+
+
+ Darklang's runtime is fully asynchronous, but it avoids the explicit
+ await keywords common in languages like JavaScript or TypeScript.
+ Instead, it uses data dependencies to manage concurrency, a
+ functional approach that ensures operations wait for their inputs
+ without exposing threading complexity. This design eliminates race
+ conditions (due to immutability) and simplifies concurrent
+ programming, aligning with functional programming's emphasis on
+ declarative concurrency models.
+
+
+
+ {/* Unicode Strings */}
+
+
+ Unicode-Aware Strings
+
+
+ Darklang's string handling is designed for modern applications,
+ using Extended Grapheme Clusters to represent characters (e.g.,
+ emojis like ๐จโ๐ฉโ๐ฆโ๐ฆ are treated as single characters). This functional
+ approach to string representation avoids the pitfalls of byte-based
+ or UTF-16 strings in older languages, ensuring predictable behavior
+ in text processing.
+
+
+
+
+ {/* Benefits Summary */}
+
+
+ Key Benefits
+
+
+
+
+
+ Reliability:
+
+ {" "}
+ Static typing and immutability ensure that compiled code is
+ robust, a critical feature for cloud backends.
+
+
+
+
+
+
+ Concurrency:
+
+ {" "}
+ Immutability and data-driven async execution simplify concurrent
+ programming, a key requirement for scalable backend services.
+
+
+
+
+
+
+ Productivity:
+
+ {" "}
+ Features like pipelines, implicit returns, and gradual typing
+ make functional programming accessible and efficient, aligning
+ with Darklang's goal of simplifying backend development.
+
+
+ );
+};
+
+export default PackageHeader;
diff --git a/src/pages/PackageDetail/components/TabContent.tsx b/src/pages/PackageDetail/components/TabContent.tsx
new file mode 100644
index 0000000..dd3f3c2
--- /dev/null
+++ b/src/pages/PackageDetail/components/TabContent.tsx
@@ -0,0 +1,197 @@
+import React from "react";
+import ActionButton from "./ActionButton";
+import { SelectedItem } from "./types";
+
+interface TabItem {
+ name: string;
+ signature?: string;
+ description: string;
+}
+
+interface TabContentProps {
+ type: "functions" | "types" | "constants";
+ selectedPackage: string;
+ sidebarItemsData: Record;
+ sidebarLoadingStates: Record;
+ searchQuery: string;
+ selectedItem: SelectedItem | null;
+ onFetchItemData: (packageName: string) => void;
+ onSearchClear: () => void;
+}
+
+const TabContent: React.FC = ({
+ type,
+ selectedPackage,
+ sidebarItemsData,
+ sidebarLoadingStates,
+ searchQuery,
+ selectedItem,
+ onFetchItemData,
+ onSearchClear,
+}) => {
+ const currentSidebarData = sidebarItemsData[selectedPackage];
+ const isLoading = sidebarLoadingStates[selectedPackage] || false;
+
+ // Get the appropriate data based on type
+ const getItemData = (): TabItem[] => {
+ if (!currentSidebarData) return [];
+
+ switch (type) {
+ case "functions":
+ return currentSidebarData.fullFunctionData || [];
+ case "types":
+ return currentSidebarData.fullTypeData || [];
+ case "constants":
+ return currentSidebarData.fullConstantData || [];
+ default:
+ return [];
+ }
+ };
+
+ const rawData = getItemData();
+
+ // Filter items based on search query
+ const filteredItems = rawData.filter((item: TabItem) => {
+ if (!searchQuery.trim()) return true;
+ const query = searchQuery.toLowerCase();
+
+ const name = item.name?.toLowerCase() || "";
+ const description = item.description?.toLowerCase() || "";
+ const signature = item.signature?.toLowerCase() || "";
+
+ return (
+ name.includes(query) ||
+ description.includes(query) ||
+ signature.includes(query)
+ );
+ });
+
+ // Get display configuration based on type
+ const getDisplayConfig = () => {
+ switch (type) {
+ case "functions":
+ return {
+ singular: "function",
+ plural: "functions",
+ color: "text-blue-dbg",
+ emptyMessage: "No functions found for this module.",
+ };
+ case "types":
+ return {
+ singular: "type",
+ plural: "types",
+ color: "text-purple-dbg",
+ emptyMessage: "No types found for this module.",
+ };
+ case "constants":
+ return {
+ singular: "constant",
+ plural: "constants",
+ color: "text-sand",
+ emptyMessage: "No constants found for this module.",
+ };
+ default:
+ return {
+ singular: "item",
+ plural: "items",
+ color: "text-gray-400",
+ emptyMessage: "No items found.",
+ };
+ }
+ };
+
+ const config = getDisplayConfig();
+
+ // Handle loading state
+ if (isLoading) {
+ return (
+
+
Loading {config.plural}...
+
+ Fetching {config.singular} information
+
+
+ );
+ }
+
+ // Handle case where we need to fetch data
+ if (!currentSidebarData && selectedPackage) {
+ onFetchItemData(selectedPackage);
+ return (
+
+
Loading {config.plural}...
+
+ Fetching {config.singular} information
+
+
+ );
+ }
+
+ // Handle empty state
+ if (filteredItems.length === 0) {
+ return (
+
+ {searchQuery ? (
+ <>
+
+ No {config.plural} found matching "{searchQuery}"
+
+
+ >
+ ) : (
+
{config.emptyMessage}
+ )}
+
+ );
+ }
+
+ return (
+
+ {searchQuery && (
+
+ Showing {filteredItems.length} of {rawData.length} {config.plural}
+