A small, zero-dependency client for the GitHub Gists API. Reads return raw gist JSON; list methods are async iterables that paginate transparently.
- Node.js ≥ 26.3
pnpm add gisty
# or: npm install gistyimport { Gisty } from 'gisty';
const gist = new Gisty({ token: process.env.GITHUB_TOKEN });
const one = await gist.fetch('aa5a315d61ae9438b18d');
for (const [name, file] of Object.entries(one.files)) {
console.log(name, file.content);
}
for await (const g of gist.all()) {
console.log(g.id, g.description);
}
const recent = await Array.fromAsync(gist.public({ limit: 50 }));
console.log(recent.length);
const created = await gist.create({ files: { 'hello.txt': 'Hello' } });
await gist.update(created.id, { description: 'updated' });
await gist.delete(created.id);new Gisty(options?)| Option | Default | Meaning |
|---|---|---|
token |
env.GITHUB_TOKEN |
Access token; omit for public reads only |
username |
none | Default user for all() |
env |
process.env |
Object to read GITHUB_TOKEN from |
baseUrl |
https://api.github.com |
API host |
timeout |
30000 |
Per-request timeout in ms; 0 disables it |
| Method | Returns | Endpoint |
|---|---|---|
fetch(id, sha?) |
one gist; sha selects a revision |
GET /gists/{id}[/{sha}] |
all(options?) |
the user's gists | GET /gists or /users/{username}/gists |
public(options?) |
recent public gists | GET /gists/public |
starred(options?) |
starred gists (token required) | GET /gists/starred |
history(id, options?) |
a gist's revisions | GET /gists/{id}/commits |
forks(id, options?) |
a gist's forks | GET /gists/{id}/forks |
comments(id, options?) |
a gist's comments | GET /gists/{id}/comments |
comment(id, commentId) |
one comment | GET /gists/{id}/comments/{commentId} |
fetch and comment resolve to a single object. The rest return async iterables; collect them with Array.fromAsync.
options:
| Key | Default | Meaning |
|---|---|---|
perPage |
100 |
Page size, max 100 |
since |
none | ISO 8601 timestamp; items updated after it |
limit |
none | Stop after this many items |
username |
constructor username |
all() only |
Writes require a token and resolve to the raw gist (delete resolves to undefined).
| Method | Returns | Endpoint |
|---|---|---|
create(gist) |
the new gist | POST /gists |
update(id, changes) |
the updated gist | PATCH /gists/{id} |
delete(id) |
undefined |
DELETE /gists/{id} |
create(gist) takes { files, description?, public? }; public defaults to false. update(id, changes) takes { files?, description? } with at least one set.
In files, a string is the file body, null deletes a file, and { filename } renames one:
await gist.update(id, {
files: {
'hello.txt': 'Hello again', // update content
'old.txt': { filename: 'new.txt' }, // rename
'draft.txt': null // delete
},
description: 'updated'
});gist.rateLimit holds the latest GitHub rate-limit state after each request:
gist.rateLimit; // { limit, remaining, reset: Temporal.Instant }A failed request throws GistError, carrying message, status, documentationUrl, rateLimit, and cause. It is raised on an HTTP error, a network failure, or a timeout:
import { Gisty, GistError } from 'gisty';
try {
await Array.fromAsync(new Gisty().starred());
} catch (err) {
if (err instanceof GistError) {
console.error(err.status, err.message);
}
}Public reads need no token. Private gists, starred(), and writes require one, passed as { token } or read from GITHUB_TOKEN.
The least-privilege fine-grained PAT for reading carries no Gists permission. Writes need Account → Gists → Read and write (GitHub has no read-only gist level). The helper script creates and verifies a token:
node examples/get-access-token.jsMIT. See LICENSE.