Skip to content

Getting Started

Chris Michael edited this page Oct 7, 2026 · 1 revision

Pudu

Getting Started

Install Pudu 0.1.3 or later, then create a project and add the package:

pudu init my-app
cd my-app
pudu install @chrismichaelps/pudu-lang-environment@0.1.0

Add .env and .env.*.local to the project's .gitignore before writing a secret into either.

A first load

Options.defaults() reads .env in the working directory. The fluent chain changes one choice at a time and ends in .load(), which comes from the Loading trait in PuduLangEnvironment.Loader — import the module even when you only call the chain. This program writes a .env into a temporary directory so it runs anywhere:

module Ex01First

import Std.Fs as Fs
import Std.Io as Io
import Std.Path as Path
import PuduLangEnvironment as Environment
import PuduLangEnvironment.Loader as Loader
import PuduLangEnvironment.Options as Options
import PuduLangEnvironment.Variables as Variables

fn start(project: Str) -> Result[Int, Fs.FsError] {
  let _written = Io.write(Path.join(project, ".env"), "PORT=8080\nDEBUG=true\nAPI_KEY=sk-test-123\n")
  match Options.defaults().inDirectory(project).withStrict().load() {
    case Ok(variables) => {
      let _port = Io.writeLine("port: " + show(Variables.int(&variables, "PORT")))
      let _debug = Io.writeLine("debug: " + show(Variables.bool(&variables, "DEBUG")))
      let _about = Io.writeLine("applied: " + show(variables.applied) + " from " + show(variables.sources.length()) + " file")
      Ok(0)
    }
    case Err(problem) => {
      let _said = Io.writeErrorLine(Environment.describe(&problem))
      Ok(1)
    }
  }
}

export fn main() -> Int {
  match Fs.withTemporaryDirectory("first-", start) {
    case Ok(status) => status
    case Err(_) => 1
  }
}

Output:

port: Ok(8080)
debug: Ok(true)
applied: ["API_KEY", "DEBUG", "PORT"] from 1 file

load answers Variables: the file's values settled over the process environment. Variables.int and Variables.bool answer Ok with the value, or a Problem naming the key. Variables.describe says how many keys the load applied and from where, and never shows a value.

withStrict() turns a missing or unreadable file into a refusal; without it a missing .env is skipped and recorded, which suits programs that also run where the real environment is set some other way.

Related

Clone this wiki locally