Content
Configure Deno
Terminal:
curl -fsSL https://deno.land/install.sh | sh
To install Deno. Then follow the terminal tips, to update the PATH variable.
Terminal:
deno upgrade
To upgrade Deno.
Terminal:
deno install -Arf jsr:@deno/deployctl
To install deployment tool.
Terminal:
deployctl --help
To check installation.
Terminal:
rm -rf $HOME/.deno
To uninstall Deno.
Terminal:
deno info
To get info about cash configuration.
DENO_DIR location: /home/user/.cache/deno Remote modules cache: /home/user/.cache/deno/deps npm modules cache: /home/user/.cache/deno/npm Emitted modules cache: /home/user/.cache/deno/gen Language server registries cache: /home/user/.cache/deno/registries Origin storage: /home/user/.cache/deno/location_data
Terminal:
rm -rf /home/user/.cache/deno
To remove recursively cashed Deno files(use previous output paths).
Manage Deno Projects
Terminal:
deno init
To create Deno project inside the terminal current folder.
Terminal:
deno init basic-project
To create Deno project inside new folder basic-project.
Execution of deno init command for already created project will skip all files created before. So your project will not be damaged.
ℹ️ Skipped creating main.ts as it already exists ℹ️ Skipped creating main_test.ts as it already exists ℹ️ Skipped creating deno.json as it already exists ✅ Project initialized Run these commands to get started # Run the program deno run main.ts # Run the program and watch for file changes deno task dev # Run the tests deno test
Terminal:
deno cache --reload my_module.ts
To force Deno to refetch and recompile modules into the cache.
Terminal:
deno vendor main.ts test.deps.ts https://deno.land/std/path/mod.ts
To download all remote dependencies of the specified modules into a local vendor folder.
Terminal:
deno run --no-remote --import-map=vendor/import_map.json main.ts
To run + force Deno use the modules in the vendor folder.
Terminal:
deno check module.ts
To type-check without execution.
Terminal:
deno run module.ts
To execute without type-check.
Terminal:
deno check --all module.ts
To also type-check remote modules and npm packages.
Terminal:
deno run --check module.ts
To type-check before execution.
Terminal:
deno run --check=all module.ts
To also type-check remote modules and npm packages before execution.
Terminal:
deno fmt file.ts
To format file.ts code according to standards.
Terminal:
deno fmt
To format recursively all files code according to standards.
At the top of the file add comment line:
// deno-lint-ignore-file
To ignore linting of this file. Can be useful in case of use any *.js libraries, f.e.vue.esm-browser.prod.js as frontend side injections, in case of soft upgrade etc.
API changes and deprecations
API changes and deprecationsTypes and Type Declarations
Types and Type DeclarationsPrivate Modules and Repositories
Private Modules and RepositoriesRuntime APIs
Runtime APIsImporting NPM Packages
main.js
import { emojify } from "npm:node-emoji@2"; console.log(emojify(":t-rex: :heart: NPM"));
Terminal:
deno run main.js
Output:
🦖 ❤️ NPM
As described in docs, using of npm packages is unstable. Do not use it without strict needs.
Copypaste from terminal:
> emojify(":heart:"); "❤️" > emojify(":t-rex:"); "🦖" >
Screenshot from terminal:
In some reasons the " symbol after the heart symbol is recolored in the black color(fail even with this simple example above). Also looks like import returns undefined which probably some trash too.
Node API Compatibility List
Node API Compatibility ListJSX import source pragma(compiler directive)
To use Preact from esm.sh, add in the source code file leading comments @jsxImportSource pragma
/** @jsxImportSource https://esm.sh/preact */ export function App() { return ( <div> <h1>Hello, world!</h1> </div> ); }
Basic Twind(tailwind-in-js) example
import { extract, install } from "https://esm.sh/@twind/core@1.1.3"; import presetTailwind from "https://esm.sh/@twind/preset-tailwind@1.1.4"; install({ presets: [ presetTailwind(), { theme: { fontFamily: { sans: ["Helvetica", "sans-serif"], serif: ["Times", "serif"], }, }, }, ], }); function renderBody() { return `<!DOCTYPE html> <html lang="en"> <body class="font-sans"> <h1 class="text(3xl blue-500)">Hello from Deno</h1> </body> </html> `; } function ssr() { const body = renderBody(); const { html, css } = extract(body); return html.replace("</head>", `<style data-twind>${css}</style></head>`); } console.log(ssr());
Basic deno-dom(DOM and HTML parser) example
import { DOMParser, initParser, } from "https://deno.land/x/deno_dom/deno-dom-wasm-noinit.ts"; (async () => { // initialize when you need it, but not at the top level await initParser(); const doc = new DOMParser().parseFromString( `<h1>Lorem ipsum dolor...</h1>`, "text/html", ); })();
Managing Dependencies
Example:
File deps.ts (use to manage dependencies).
export * as http from "jsr:@std/http"; export * as path from "jsr:@std/path"; export { add, multiply, } as remote_lib from "https://x.nest.land/ramda@0.27.0/source/index.js"; export { add, multiply, } as local_lib from "./arithmetic.ts";
File arithmetic.ts.
/** * arithmetic.ts */ export function add(a: number, b: number): number { return a + b; } export function multiply(a: number, b: number): number { return a * b; } export interface Foo {} export class Bar {} export const bang = "bang";
File main.ts.
import { path, remote_lib } from "./deps.ts";
By using a lock file (with the --lock command line flag), you can ensure that the code pulled from a URL is the same as it was during initial development.
For production deployment use deno vendor subcommand to manage the host of the URL goes down case.
To force deno to refetch and recompile modules into the cache, use deno cache --reload target_module.ts
Permissions(manage Deno security model)
PermissionsManage Data (Fetch, Read, Write, Append)
To make a call over the web possible, add the --allow-net flag to the deno run terminal command.
To convert a Deno file into a writable and readable stream or read and write files add --allow-read --allow-write flags to the deno run terminal command.
deno run --allow-read --allow-write --allow-net manage_data.ts
The manage_data.ts file.
/** Output: JSON Data */ const json_response = await fetch("https://api.github.com/users/denoland"); const json_data = await json_response.json(); console.log(json_data); /** Output: HTML Data */ const text_response = await fetch("https://deno.land/"); const text_data = await text_response.text(); console.log(text_data); /** Output: Error Message */ try { await fetch("https://does.not.exist/"); } catch (error) { console.log(error); } /** Receiving a file */ const file_response = await fetch("https://deno.land/logo.svg"); if (file_response.body) { const save_here = await Deno.open( "./logo.svg", { write: true, create: true } ); await file_response.body.pipeTo(save_here.writable); } /** Sending a file */ const send_file = await Deno.open( "./logo.svg", { read: true } ); await fetch( "https://example.com/", { method: "POST", body: send_file.readable } ); /** read file */ const text = await Deno.readTextFile("./people.json"); console.log(text); /** write file */ await Deno.writeTextFile("./hello.txt", "Hello World!"); console.log("File written to ./hello.txt"); /** append to the file */ await Deno.writeTextFile("./hello.txt", "This text will be appended.", { append: true, }); /** write serialized json object to a file */ function writeJson(path: string, data: object): string { try { /** can be "await Deno.writeTextFile" for async function */ Deno.writeTextFileSync(path, JSON.stringify(data)); return "written to " + path; } catch (e) { return e.message; } } console.log(writeJson("./data.json", { hello: "World" }));
Making Scripts Executable (Unix only)
Making Scripts Executable With a Hashbang (Shebang)Manage External Environment
The env runs a program in a modified environment.
(--allow-env) Runtime Deno.Env interface to interact with the process environment variables.
(--allow-env) Runtime Deno.env provides environment variables.
(--allow-env) Runtime Deno.args accesses the command line arguments.
ReadableStream interface represents a readable stream of byte data.
WritableStream interface provides a standard abstraction for writing streaming data to a destination, known as a sink.
File System Deno.FsFile.readable is used to get a readable stream from the file. This readable stream closes the file when it is finished reading, so it is not necessary to close the file explicitly.
File System Deno.FsFile.writable is used to write the contents of the file.
(--allow-read) File System Deno.open is used to get a handle to a file.
(--allow-write) File System Deno.remove Removes the named file or directory.
await Deno.remove("/path/to/empty_dir/or/file"); await Deno.remove("/path/to/populated_dir/or/file", { recursive: true });
(--allow-read --allow-write) File System Deno.rename
(--allow-write) File System Deno.mkdir creates a new directory with the specified path.
(--allow-read --allow-write) File System Deno.create creates a new directory with the specified path.
(--allow-read) File System Deno.readDir reads the directory given by path and returns an async iterable of Deno.DirEntry information about a directory entry.
for await (const dirEntry of Deno.readDir("/")) { console.log(dirEntry.name); }
(--allow-write) File System Deno.chmod changes the permission of a specific file/directory of specified path using sequence of 3 octal numbers.
await Deno.chmod("/path/to/file", 0o666);
Manage built-in KV(key/value) Database
Steps to create the database, place it in desirable folder and use. Suitable only for debug needs. Deploy does not allow to use custom database.
1. Create database in project root folder. Include const kv = await Deno.openKv("db"); syntax in your main.ts file. After the first success execution the database files will be created in root folder.
2. Create desirable folder structure and move created database files inside destination folder. After that check the correct path to new database destination using next syntax in main.ts. Correct the appendix of join according to your file structure.
import { join } from "https://deno.land/std@0.224.0/path/mod.ts"; const db_path = join(Deno.cwd(), "some/path/to/db"); console.log(db_path); // const kv = await Deno.openKv("db"); // commented to avoid recreate in root
3. When db_path looks correct, use it to manage database.
import { join } from "https://deno.land/std@0.224.0/path/mod.ts"; const db_path = join(Deno.cwd(), "correct/path/to/db"); console.log(db_path); const kv = await Deno.openKv(db_path); console.log(kv); // to print and confirm some structure in console // create interfaces for later type assertion (as TypeName) // also interfaces can be placed in separated file f.e. "model.ts" and then imported using // import { Fruit, Product } from "./model.ts"; export interface Fruit { fruit_name: string; growed_in: string; } export interface Product { product_name: string; production_year: number; } // prepare data to use in database // ----------------- // item for database const fresh_fruit: Fruit = { name: "ice orange"; growed_in: "Antarctica"; }; // -------------------------------------- // database category, like sql table name const category = "fruits"; // ----------------------------- // unique identifier of the item const unique_key = fresh_fruit.name; // --------------------------- // set recording into database await kv.set([category, unique_key], fresh_fruit); // ---------------------- // get item from database using type assertion const polar_fruit_one = await kv.get(["fruits", "ice orange"]); const ac = r.value as Fruit; // ------------------------------------------ // get item from database using inline syntax const polar_fruit_two = await kv.get<Fruit>(["fruits", "ice_orange"]); // ----------------------- // some check (demo needs) console.log( (polar_fruit_one.growed_in === polar_fruit_two.growed_in) && (polar_fruit_two.growed_in === "Antarctica") );
After the correct settings, you can use key/value database in deno deploy as part of deployed repository. Under the hood deno uses external provider to manage built-in databases. Free plan has some limitations(according to official docs).
Debug Development(deno.json tasks)
A deno.json file, created using deno init command.
{ "tasks": { "dev": "deno run --watch main.ts", "test": "deno run --allow-all --unstable-kv main_test.ts", "bang": "deno run --inspect-wait --allow-all --unstable-kv main.ts" } }
The --inspect-wait flag, forcing the execution to wait up to chrome(or chromium) debugger will be connected, using chrome://inspect/ -> reload gui in browser.