LSP & Language Tooling Fund
Fund the Language Server Protocol (LSP) engine to enable real-time IDE diagnostics and autocompletion.
View goal →Public alpha · Blacklight Foundation
A high-visibility, general-purpose language for humans and AI.
Linux x86_64 / macOS (Apple Silicon)
$curl -fsSL https://ultraviolet-lang.org/install | sh Windows x86_64
$powershell -c "irm https://ultraviolet-lang.org/install.ps1 | iex" Installs the current packaged compiler release and uses published SHA-256 metadata when available. Prefer manual downloads? GitHub releases or build from source.
Integrity
... SHA-256
GitHub status unavailable
Twelve language systems designed so that what the compiler checks is also what the reader sees. Pick a feature to see real Ultraviolet source.
Review & safety
Concurrency & compute
Systems & interop
Modal programming
Model resources, protocols, async work, and execution lifecycles as explicit states with checked transitions.
public modal Session { @Disconnected { public transition connect(net: unique Net) -> @Connected { let socket = net~>open("wss://updates") return Session@Connected { socket: socket } } } @Connected { public socket: unique Socket public transition close(reason: CloseReason) -> @Closed { return Session@Closed { receipt: self.socket~>shutdown(reason) } } } @Closed { public receipt: CloseReceipt }} Contracts
Preconditions, postconditions, invariants, and foreign contracts make generated assumptions part of source.
public procedure normalizedRatio( numerator: f32, denominator: f32) -> Percent|: denominator > 0.0 && numerator >= 0.0 && numerator <= denominator |= @result.value >= 0.0 && @result.value <= 100.0{ let scaled: f32 = (numerator / denominator) * 100.0 return Percent { value: scaled }}public procedure allocateWindow(start: usize, count: usize, total: usize) -> Window|: count > 0 && count <= total && start <= total - count |= @result.end <= total{ let end = start + count return Window { start: start, end: end }} Permissions and binding state
move, const, shared, and unique separate transfer of responsibility from access permission.
public procedure stageUpload(move packet: Packet, sink: shared Sink, log: shared AuditLog) { let header_bits: const PacketHeaderBits = packet~>headerBits() %write log { log~>record(copy header_bits) } %write sink { sink~>write(move packet) }}public procedure rotate(move old: unique Buffer, move next: unique Buffer) -> unique Buffer { releaseBuffer(move old) return next} Capability Context
Runtime authority flows through explicit Context fields and attenuated capability values.
public procedure main(move ctx: Context) { let sys = ctx.sys let io = ctx.io let net = ctx.net let arg_count: usize = sys~>argument_count() let workspace = io~>restrict("workspace") let updates = net~>restrict_to_host("updates.ultraviolet.dev") if workspace~>exists("Ultraviolet.toml") { io~>write_stdout("manifest found\n") } if arg_count > 1 { let command = sys~>argument(1) submitUpdateCheck(updates, command) }} Structured parallelism
parallel, spawn, dispatch, wait, race, and async state share one visible execution model.
public procedure rebuild(ctx: Context, jobs: shared Jobs, index: shared Index, shards: usize) { parallel ctx.cpu { dispatch shard in 0..shards { let prefetch = spawn { prepareShard(shard) } %read jobs.shards[%shard] { let rows: RowBatch = jobs.shards[shard]~>load() wait prefetch %write index.shards[%shard] { index.shards[shard]~>replace(move rows) } } } }} Async operations
Future, Stream, sync, race, all, and yield release keep suspension and composition visible.
public procedure loadProfile(user: UserId, cache: Cache, api: Api) -> Profile | ProfileError { let warmup = all { cache~>warmAsync(user), api~>preflightAsync(user) } sync warmup let cached: Future<Profile, ProfileError> = cache~>lookupAsync(user) let remote: Future<Profile, ProfileError> = api~>fetchAsync(user) return race { cached -> | hit | hit, remote -> | fresh | fresh, }} CPU + GPU programming
Write code for CPU or GPU execution in one language model, with execution domains exposed as typed capabilities.
public procedure scanLuma(ctx: Context, pixels: [f32; 1024]) { let pixel_count: usize = 1024 parallel ctx.gpu { dispatch pixel in 0..pixel_count { let luma: f32 = pixels[pixel] classifyPixel(pixel, luma) } } let tile_count: usize = 16 parallel ctx.cpu { dispatch tile in 0..tile_count { summarizeTile(tile) } }} Keyed shared access
shared data is synchronized through explicit key paths, modes, and lexical scopes.
public procedure commitShard(id: usize, cache: shared Cache, index: shared Index) { let rows = rowCount(id) let sum = checksum(id) %write cache.entries[%id] { cache.entries[id].rows = rows cache.entries[id].checksum = sum } %write index.shards[%id] { index.shards[id].checksum = sum } %read cache.metrics { let total = cache.metrics.total auditShard(id, total) }} Abstraction and polymorphism
Classes, generic bounds, and dynamic class objects expose abstraction choices in source.
public class Renderer { public procedure render(~, value: const User) -> string@Managed}public record JsonRenderer <: Renderer { public override procedure render(~, value: const User) -> string@Managed { return renderJson(value, 2) }}public procedure renderStatic<TRenderer <: Renderer>(r: TRenderer, value: const User) -> string@Managed { return r~>render(value)}public procedure renderDynamic(renderer: $Renderer, value: const User) -> string@Managed { return renderer~>render(value)} Compile-time generation
comptime, quote/splice, reflection, and emission support controlled generated source.
Foreign function interface
extern blocks, C layout, unsafe calls, and FFI attributes make foreign boundaries inspectable.
#layout(C)public record NativePoint { public x: f32 public y: f32}#library(name: "uvmath", kind: "static")public extern "C" { #mangle("uv_distance") public procedure native_distance(a: NativePoint, b: NativePoint) -> f32}public procedure distanceFromOrigin(point: NativePoint) -> f32 { let origin = NativePoint { x: 0.0, y: 0.0 } unsafe { return native_distance(point, origin) }} Memory regions and frames
Region aliases and frame reset points make temporary allocation lifetimes visible in source.
public procedure decodeBatch(source: bytes@View) -> BatchSummary { var summary = BatchSummary { rows: 0, checksum: 0 } region as scratch { let header = scratch ^ Header { count: source~>length() } scratch.frame { let row = scratch ^ RowScratch { index: 0, width: header.count } summary.rows = scanRows(source, row) } scratch.frame { let table = scratch ^ IndexScratch { slots: summary.rows } summary.checksum = foldChecksum(table) } } return summary} Blacklight Foundation funds compiler and runtime work, examples, diagnostics, CI, documentation, and community infrastructure — with public goals and public reporting.
See support optionsLSP & Language Tooling Fund
Fund the Language Server Protocol (LSP) engine to enable real-time IDE diagnostics and autocompletion.
View goal →Standard Library & Package Manager Fund
Fund the initial release of the package manager (uvpm) and core standard library modules.
View goal →Wasm Target & Compiler Playground Fund
Fund compiler support for WebAssembly (Wasm) and build an interactive browser-based playground.
View goal →