Monorepo Architecture with pnpm Workspace, Turborepo & Changesets ๐ฆ
<p>When you're developing a project with multiple packages, managing each one in its own repo can quickly turn into a nightmare. In this article, we'll set up a monorepo architecture from scratch using <strong>pnpm workspace</strong>, speed up build processes with <strong>Turborepo</strong>, and build an automated NPM publish pipeline with <strong>Changesets</strong>.</p> <h2> ๐๏ธ What Is a Monorepo? </h2> <p>Let's say you're building a design system. You have a core package, a theme package, and a utils package. Now imagine keeping all of these in <strong>separate repositories</strong>.</p> <p>When you fix a bug in the core package, what happens? You switch to the theme repo and update the dependency. Then you switch to the utils repo. You open separate PRs for each, wait for separate CI/
When you're developing a project with multiple packages, managing each one in its own repo can quickly turn into a nightmare. In this article, we'll set up a monorepo architecture from scratch using pnpm workspace, speed up build processes with Turborepo, and build an automated NPM publish pipeline with Changesets.
๐๏ธ What Is a Monorepo?
Let's say you're building a design system. You have a core package, a theme package, and a utils package. Now imagine keeping all of these in separate repositories.
When you fix a bug in the core package, what happens? You switch to the theme repo and update the dependency. Then you switch to the utils repo. You open separate PRs for each, wait for separate CI/CD pipelines, and publish separately. Even with just three packages, this process is exhausting โ with ten, it's a total nightmare.
This is exactly where the monorepo comes in.
A monorepo is an architectural approach that houses multiple projects under a single repository. All your packages live in the same repo, share the same commit history, and can easily reference each other.
So why does this matter? Let's look at a few key advantages:
โ Code sharing in one place: Shared utilities, types, and configurations are instantly available to all packages. No need to wait for an NPM publish.
โ Atomic changes: You can make a change that affects multiple packages in a single commit. No more cross-repo PR synchronization headaches.
โ Consistent tooling: ESLint, Prettier, and TypeScript configurations are managed from a single source. The question "Why does this repo have different rules?" becomes a thing of the past.
โ Easy onboarding: When a new developer joins the project, a single git clone and pnpm install brings up the entire ecosystem.
๐ง Setting Up a pnpm Workspace
pnpm stands out among Node.js package managers for its monorepo support. Unlike npm and yarn, its content-addressable store keeps all dependencies in a global store and links them into your projects via hard links. This saves a massive amount of disk space.
Let's walk through setting up a monorepo architecture with pnpm workspace using a sample project.
Step 1: Install pnpm and Initialize the Project
Install pnpm globally:
npm install -g pnpm
Enter fullscreen mode
Exit fullscreen mode
Then initialize a new monorepo project:
mkdir my-design-system cd my-design-system pnpm init git initmkdir my-design-system cd my-design-system pnpm init git initEnter fullscreen mode
Exit fullscreen mode
โ The pnpm init command creates a package.json file at the root level.
โ This file will serve as the main entry point for your monorepo. All workspace scripts will be managed from here.
Step 2: Create pnpm-workspace.yaml
Create a pnpm-workspace.yaml file in the project root:
packages:
- "packages/*"
- "apps/*"
- "website"`
Enter fullscreen mode
Exit fullscreen mode
โ The packages/* expression defines each folder under the packages directory as a separate workspace package.*
โ apps/* includes applications, and website adds the documentation site to the workspace.*
โ Without this file, pnpm won't recognize your project as a monorepo.
Step 3: Configure the Root package.json
Configure the root package.json for the monorepo:
{ "name": "my-design-system", "private": true, "scripts": { "dev": "turbo run dev", "build": "turbo run build", "test": "turbo run test", "lint": "turbo run lint", "clean": "turbo run clean" }, "devDependencies": { "turbo": "^2.3.1", "typescript": "^5.7.2", "tsup": "^8.3.5", "vitest": "^2.1.6", "prettier": "^3.4.1" }, "packageManager": "[email protected]", "engines": { "node": ">=18.0.0" } }{ "name": "my-design-system", "private": true, "scripts": { "dev": "turbo run dev", "build": "turbo run build", "test": "turbo run test", "lint": "turbo run lint", "clean": "turbo run clean" }, "devDependencies": { "turbo": "^2.3.1", "typescript": "^5.7.2", "tsup": "^8.3.5", "vitest": "^2.1.6", "prettier": "^3.4.1" }, "packageManager": "[email protected]", "engines": { "node": ">=18.0.0" } }Enter fullscreen mode
Exit fullscreen mode
โ "private": true is a critical setting. It prevents the root package from being accidentally published to NPM.
โ The "packageManager" field ensures that everyone who clones the project uses the same pnpm version. Corepack reads this field and automatically activates the correct package manager.
โ Shared devDependencies (like TypeScript and Prettier) are installed at the root, so individual packages don't need to install them separately.
Step 4: Create the Project Structure
Now let's create the folder structure:
mkdir -p packages/core mkdir -p packages/utils mkdir -p packages/theme mkdir -p apps/docsmkdir -p packages/core mkdir -p packages/utils mkdir -p packages/theme mkdir -p apps/docsEnter fullscreen mode
Exit fullscreen mode
A typical monorepo structure looks like this:
my-design-system/ โโโ packages/ โ โโโ core/ # Core library โ โโโ utils/ # Shared utility functions โ โโโ theme/ # Theme and style definitions โโโ apps/ โ โโโ docs/ # Documentation app โโโ .changeset/ # Changesets configuration โโโ .github/ # CI/CD workflows โโโ package.json # Root workspace config โโโ pnpm-workspace.yaml # Workspace definition โโโ turbo.json # Turborepo pipeline โโโ tsconfig.base.json # Shared TypeScript config โโโ pnpm-lock.yaml # Lock filemy-design-system/ โโโ packages/ โ โโโ core/ # Core library โ โโโ utils/ # Shared utility functions โ โโโ theme/ # Theme and style definitions โโโ apps/ โ โโโ docs/ # Documentation app โโโ .changeset/ # Changesets configuration โโโ .github/ # CI/CD workflows โโโ package.json # Root workspace config โโโ pnpm-workspace.yaml # Workspace definition โโโ turbo.json # Turborepo pipeline โโโ tsconfig.base.json # Shared TypeScript config โโโ pnpm-lock.yaml # Lock fileEnter fullscreen mode
Exit fullscreen mode
โ Libraries and shared modules live under packages/. Each one can be published as an independent npm package.
โ Applications that consume these packages go under apps/.
โ Configuration files at the root apply across the entire monorepo.
You also need to initialize each sub-package. For example, for packages/core:
cd packages/core pnpm initcd packages/core pnpm initEnter fullscreen mode
Exit fullscreen mode
This creates a package.json for each package. Using namespaced package names is a good practice:
{ "name": "@myds/core", "version": "0.1.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsup src/index.ts --format cjs,esm --dts", "dev": "tsup src/index.ts --format cjs,esm --dts --watch" } }{ "name": "@myds/core", "version": "0.1.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsup src/index.ts --format cjs,esm --dts", "dev": "tsup src/index.ts --format cjs,esm --dts --watch" } }Enter fullscreen mode
Exit fullscreen mode
โ Scoped names like @myds/core prevent namespace collisions on NPM.
โ The main and types fields ensure that other packages resolve the correct files when importing this package.
โ tsup is a great tool for quickly bundling TypeScript packages. It produces output in both CJS and ESM formats.
๐ Cross-Package Dependency Management with the workspace Protocol
One of the most powerful features of a monorepo is the ability for packages to reference each other locally. pnpm achieves this through the workspace: protocol.
Let's make this concrete with an example. Say the @myds/theme package depends on @myds/core. You'd define this dependency like so:
{ "name": "@myds/theme", "version": "0.4.0", "dependencies": { "@myds/core": "workspace:*" } }{ "name": "@myds/theme", "version": "0.4.0", "dependencies": { "@myds/core": "workspace:*" } }Enter fullscreen mode
Exit fullscreen mode
โ The workspace:* expression tells pnpm: "Don't download this package from the npm registry โ use the local version from the workspace." โ During development, packages are linked together via symlinks. Any change you make in core is instantly reflected in theme.*
But what happens at publish time? Here's the beauty of pnpm: when you run pnpm publish, workspace:* is automatically converted to the actual version number.*
So while package.json looks like this during development:
{ "dependencies": { "@myds/core": "workspace:*" } }{ "dependencies": { "@myds/core": "workspace:*" } }Enter fullscreen mode
Exit fullscreen mode
It becomes this when published to NPM:
{ "dependencies": { "@myds/core": "0.4.0" } }{ "dependencies": { "@myds/core": "0.4.0" } }Enter fullscreen mode
Exit fullscreen mode
Variants of the workspace Protocol
pnpm offers several workspace protocol variants:
โ workspace:* is the most commonly used variant. It means "use whatever version is currently in the workspace." At publish time, it resolves to an exact version (e.g., "0.4.0").*
โ workspace:^ resolves to a caret range at publish time (e.g., "^0.4.0"). This allows minor and patch updates.
โ workspace:~ resolves to a tilde range at publish time (e.g., "~0.4.0"). This allows only patch updates.
Here's my take on when to use which: if you always publish all packages together, workspace:* is sufficient. But if you want consumers to be able to mix different versions, workspace:^ offers more flexibility.*
Adding Dependencies Between Packages
To add one workspace package as a dependency of another, use the --filter flag:
pnpm add @myds/core --filter @myds/theme
Enter fullscreen mode
Exit fullscreen mode
โ The --filter flag runs the command only in the specified package.
โ pnpm automatically adds the dependency as workspace:^ (if it exists in the workspace).
You can also run scripts across all dependents of a specific package:
# Build @myds/core and all packages that depend on it pnpm --filter "@myds/core..." build# Build @myds/core and all packages that depend on it pnpm --filter "@myds/core..." buildEnter fullscreen mode
Exit fullscreen mode
To add a dependency to the root workspace, use the --workspace-root (or -w for short) flag:
pnpm add -D typescript --workspace-root
Enter fullscreen mode
Exit fullscreen mode
โก Build Orchestration with Turborepo
While pnpm workspace alone is sufficient for package management and linking, build processes get more complex as the number of packages grows. Questions like "Which package should be built first?" and "Do we really need to rebuild packages that haven't changed?" start to come up.
This is exactly where Turborepo steps in. Turborepo is a build system developed by Vercel that works directly with pnpm workspace. It reads pnpm's workspace structure, analyzes the dependency graph between packages, and optimizes tasks accordingly. It has two core features:
โ Smart task scheduling: It analyzes the dependency graph between packages and automatically determines the build order. Packages that don't depend on each other are run in parallel.
โ Hard caching: If a package hasn't changed, it restores the previous build output from cache. While the first build might take 30 seconds, a cached build can complete in 0.2 seconds.
Let's Set Up Turborepo
Add turbo to the root package.json:
pnpm add -D turbo --workspace-root
Enter fullscreen mode
Exit fullscreen mode
โ The --workspace-root flag (or -w for short) installs the package at the root workspace, making turbo available across the entire monorepo.
turbo.json Configuration
Create a turbo.json file at the project root:
{ "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "dev": { "cache": false, "persistent": true }, "test": { "dependsOn": ["build"], "outputs": [] }, "test:watch": { "cache": false, "persistent": true }, "lint": { "outputs": [] }, "clean": { "cache": false }, "check-types": { "dependsOn": ["^build"], "outputs": [] } } }{ "$schema": "https://turbo.build/schema.json", "tasks": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "dev": { "cache": false, "persistent": true }, "test": { "dependsOn": ["build"], "outputs": [] }, "test:watch": { "cache": false, "persistent": true }, "lint": { "outputs": [] }, "clean": { "cache": false }, "check-types": { "dependsOn": ["^build"], "outputs": [] } } }Enter fullscreen mode
Exit fullscreen mode
Let's pause here and understand something important: the ^ in "dependsOn": ["^build"] is crucial. It means "run my dependencies' build task first, then build me." So before @myds/theme is built, its dependency @myds/core gets built first.
โ "outputs": ["dist/"] tells Turborepo which files to cache. On the next build, if the source code hasn't changed, the dist/ folder is restored from cache.
โ "cache": false disables caching for certain tasks. Caching doesn't make sense for long-running (persistent) tasks like dev servers.
โ "persistent": true keeps the task running in the background. This is necessary for scenarios like dev servers and watch mode.
Now you can build all packages with a single command:
pnpm build
This runs turbo run build
Turborepo analyzes the dependency graph
Builds in order: first core, then theme, then utils...
Restores unchanged packages from cache`
Enter fullscreen mode
Exit fullscreen mode
๐ฆ Version Management with Changesets
One of the trickiest aspects of a monorepo is version management. You have multiple packages, each potentially with its own independent version number. How do you decide which one to bump and when, or how to generate the changelog?
This is exactly where Changesets comes in. Changesets is a versioning tool that lets you record each change as a small markdown file.
Step 1: Install Changesets
pnpm add -D @changesets/cli --workspace-root pnpm changeset initpnpm add -D @changesets/cli --workspace-root pnpm changeset initEnter fullscreen mode
Exit fullscreen mode
โ The changeset init command creates a .changeset/ directory in your project. โ Inside this directory, you'll find a config.json and a README.md file.
Step 2: Configure Changesets
Configure the .changeset/config.json file for your project:
{ "$schema": "https://unpkg.com/@changesets/[email protected]/schema.json", "changelog": [ "@changesets/changelog-github", { "repo": "your-org/your-monorepo" } ], "commit": false, "fixed": [], "linked": [["@myds/*"]], "access": "public", "baseBranch": "master", "updateInternalDependencies": "patch", "ignore": [] }{ "$schema": "https://unpkg.com/@changesets/[email protected]/schema.json", "changelog": [ "@changesets/changelog-github", { "repo": "your-org/your-monorepo" } ], "commit": false, "fixed": [], "linked": [["@myds/*"]], "access": "public", "baseBranch": "master", "updateInternalDependencies": "patch", "ignore": [] }Enter fullscreen mode
Exit fullscreen mode
Let's break down each of these settings:
โ In the changelog section, we're using @changesets/changelog-github. This automatically adds PR links and contributor information to the changelog. Let's install this package as well:
pnpm add -D @changesets/changelog-github --workspace-root
Enter fullscreen mode
Exit fullscreen mode
โ The linked field is very important. [["@myds/"]] tells Changesets that the versions of all packages under the @myds scope are linked together. If one gets a major bump, they all do.
โ "access": "public" ensures that scoped packages (like @myds/core) are published as public on NPM. Without this setting, scoped packages default to private and will throw an error during publish.
โ "updateInternalDependencies": "patch" automatically applies a patch bump to the internal dependency versions of packages that depend on an updated package.
โ "baseBranch": "master" determines which branch Changesets uses as its baseline. Depending on your project, this could be main or master.
Step 3: Create a Changeset
When you make a change, create a changeset file before opening a PR:
pnpm changeset
Enter fullscreen mode
Exit fullscreen mode
This launches an interactive wizard:
๐ฆ Which packages would you like to include? โฏ @myds/core โฏ @myds/theme โฏ @myds/utils๐ฆ Which packages would you like to include? โฏ @myds/core โฏ @myds/theme โฏ @myds/utils๐ฆ Which packages should have a major bump? ๐ฆ Which packages should have a minor bump?
๐ฆ Summary: Added dark mode support to the core package`
Enter fullscreen mode
Exit fullscreen mode
This wizard creates a randomly named markdown file in the .changeset/ directory:
--- "@myds/core": minor "@myds/theme": patch ------ "@myds/core": minor "@myds/theme": patch ---Added dark mode support to the core package. Updated related color variables in the theme package.`
Enter fullscreen mode
Exit fullscreen mode
โ The frontmatter section specifies which package gets bumped at which level. โ The text below becomes the description added to the changelog. โ This file is included in the commit and submitted for review along with the PR.
Step 4: Apply the Versions
Once all changesets have been collected, apply the versions:
pnpm changeset version
Enter fullscreen mode
Exit fullscreen mode
โ This command reads all changeset files. โ Updates the version numbers in the relevant packages' package.json files. โ Automatically creates/updates each package's CHANGELOG.md. โ Deletes the consumed changeset files.
Step 5: Publish
After versions have been applied, publish:
pnpm changeset publish
Enter fullscreen mode
Exit fullscreen mode
This publishes all changed packages to the NPM registry. But are you going to do this manually every time? Of course not! In the next section, we'll automate this entire process ๐
๐ Automated NPM Publishing with GitHub Actions
Enough theory โ time to get our hands dirty! ๐ ๏ธ The real power of Changesets shines when combined with GitHub Actions. Let's build a CI/CD pipeline step by step.
Step 1: Create an NPM Token
First, you need to create an Automation Token on NPM:
โ Go to your profile settings on npmjs.com.
โ In the Access Tokens section, select Generate New Token.
โ Set the token type to Automation. This type allows publishing without requiring 2FA.
โ Copy the generated token (it's only shown once!).
Step 2: Add Tokens to GitHub Secrets
In your GitHub repo, go to Settings > Secrets and variables > Actions and add the following secret:
โ NPM_TOKEN: The NPM automation token you just created.
GITHUB_TOKEN is automatically provided by GitHub for every workflow run, so you don't need to set it up manually.
Step 3: Configure Repository Permissions
In your GitHub repo, go to Settings > Actions > General:
โ Under Workflow permissions, enable the "Read and write permissions" option.
โ Check the "Allow GitHub Actions to create and approve pull requests" checkbox.
Without these settings, the Changesets bot won't be able to create PRs.
Step 4: Create the Release Workflow File
Now create the .github/workflows/release.yml file:
name: Release
on: push: branches:
- master
concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: false
permissions: contents: write pull-requests: write packages: write id-token: write
jobs: release: name: Release runs-on: ubuntu-latest steps:
-
name: Checkout Repo uses: actions/checkout@v4 with: fetch-depth: 0
-
name: Setup pnpm uses: pnpm/action-setup@v4
-
name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: "pnpm" registry-url: "https://registry.npmjs.org"
-
name: Install Dependencies run: pnpm install --frozen-lockfile
-
name: Build All Packages run: pnpm build
-
name: Create Release Pull Request or Publish id: changesets uses: changesets/action@v1 with: commit: "chore: update versions" title: "chore: update versions" publish: pnpm run ci:publish env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}`
Enter fullscreen mode
Exit fullscreen mode
There's a lot going on in this workflow. Let's break it down piece by piece:
โ The concurrency setting prevents multiple release workflows from running simultaneously. If a new push comes in while a publish is in progress, the old workflow isn't cancelled โ instead, the new one waits in the queue.
โ The permissions block gives the workflow the authority to write to the repo, create PRs, and publish packages.
โ fetch-depth: 0 pulls the full git history. Changesets needs the commit history to calculate versions.
โ pnpm/action-setup@v4 installs pnpm in the CI environment. It reads the packageManager field from package.json to install the correct version.
โ --frozen-lockfile is a critical flag for CI. It installs the exact same dependencies as specified in the lock file. If pnpm-lock.yaml is out of date, it throws an error.
โ changesets/action@v1 is the action that does all the heavy lifting. It handles two different scenarios:
Scenario A: If there are pending changeset files in the .changeset/ directory, it creates or updates a "Version Packages" PR. This PR contains the version bumps and changelog updates.
Scenario B: If there are no pending changesets (i.e., after the Version Packages PR has been merged), it runs the publish command to publish the packages to NPM.
Step 5: Define the ci:publish Script
Add the publish script to the root package.json:
{ "scripts": { "ci:publish": "pnpm publish -r --access public" } }{ "scripts": { "ci:publish": "pnpm publish -r --access public" } }Enter fullscreen mode
Exit fullscreen mode
โ The -r flag (recursive) publishes all workspace packages. โ --access public ensures that scoped packages are published as public.
Changeset Bot
Optionally, you can install the Changeset Bot from github.com/apps/changeset-bot on your repo. This bot checks whether PRs include a changeset file and leaves a warning comment if they don't.
๐ฏ Demo: The Tuvix.js Monorepo Project
If you'd like to see the entire architecture described in this article in action, check out the Tuvix.js project I've been developing. Tuvix.js is a lightweight micro frontend framework that uses exactly the stack covered in this article:
โ pnpm workspace managing 14+ packages in a single repo
โ Turborepo for build orchestration and caching
โ Changesets for version management and automated NPM publishing
โ GitHub Actions for the CI/CD pipeline
You can explore the pnpm-workspace.yaml, turbo.json, .changeset/config.json, and GitHub Actions workflow files directly in the repository.
Check out the repo here ๐
github.com/yasinatesim/tuvix.js
๐ฌ Feedback
While writing this article, I used my own notes for identifying sources and research, the Claude Opus 4.6 model for proofreading and additional research, and the Gemini 3 Pro Preview 2k (Nano Banana Pro) model for generating images.
I welcome any advice, suggestions, or feedback on this article. If you'd like to get in touch, you can reach me through my social media links on my website or via LinkedIn.
Best, Yasin ๐ค
๐ Resources Used While Writing This Article
-
pnpm Workspaces โ Official documentation for pnpm's workspace feature
-
Using Changesets with pnpm โ Guide on Changesets integration with pnpm
-
Turborepo - Structuring a Repository โ Turborepo's monorepo structuring documentation
-
Changesets GitHub Action โ Official Changesets GitHub Action repository and usage guide
-
Tuvix.js GitHub Repository โ My micro frontend framework, this is monorepo project referenced in this article
DEV Community
https://dev.to/yasinatesim/monorepo-architecture-with-pnpm-workspace-turborepo-changesets-g0jSign in to highlight and annotate this article

Conversation starters
Daily AI Digest
Get the top 5 AI stories delivered to your inbox every morning.
More about
claudegeminimodelQuantios Launches Agentic AI Capabilities to Transform Corporate, Trust, and Fund Services - Hubbis
<a href="https://news.google.com/rss/articles/CBMitwFBVV95cUxQVUNuSVVjVUNXOXhxRVNjRkREMzVPMzdMLXRZTW43UUZ3LXUtUHdFdHhWcXNWb2x6WW1fZ1M4XzdkeUg4WFRNYkV5VlZMWk5CcHlDS05QWHJLZ2dyOGpUalJpaFdDOWJmNmNueXRPWHNZV2F2UUttU28xUnF6ZnpRM0FtTzBDcmZqMUd5UWVGWldWYkV1MVB0a3VlNGgxN1RWMnc0NEM3LWIta1JjMDhVQjQwQW1IYVU?oc=5" target="_blank">Quantios Launches Agentic AI Capabilities to Transform Corporate, Trust, and Fund Services</a> <font color="#6f6f6f">Hubbis</font>
Exclusive | Caltech Researchers Claim Radical Compression of High-Fidelity AI Models - WSJ
<a href="https://news.google.com/rss/articles/CBMiuANBVV95cUxPS1dHbVBVRkY0cWFQLXZyQjJxZlo3cmlOdFdTU0RMTjlsSzI0R214NndpUy1Ka0JrX3RRMUtjQWcya05QY0MxNlNETldUUS02allHeFN4WFRCeUx4OTJxWmVKZ1RNemxLalVTRVd4amtYOEVPdFdCcktWSkhDZnF5SG9DbXpNcTBiRTU5UnBQbV9LekV3UEtqVFB3UGhYS3BGc3RQMDkyY1dfbmJ3QllPa1V5T08wd3RXTDdscHJINUdWV1hHTTBSVG9lbzVLc1Z0VlFHQlpuLWZJZHY4UEFDLU03YzZaZHBlNFc4dWhOTVh3aXJNSGV3UGFjaGFFMkFLcWdwOFg1YUE4eU5aUldycWVpbGQtc3U2MVFyRWUtWTB6N1lxVi1ZUWNhaUk2SURaUHJJUHg5VXFra1hEbTRaY0Nncm9ZaUZkbG0wMVZnUkRTWDZNeEVHRlV6eXhYQ3l1d2luYTZkc1JmRnBocmFHVHMtNkd5YU9jZXdCOE9faGN0dVdIR2tZOXRDSG9VYndjWVZCbzVDUkJCbVJfVFVIV2l0Vl85Zm90enRwbVd1WEtMRzJwdG1mSQ?oc=5" target="_blank">Exclusive | Caltech Researchers Claim Radical Compression of High-Fidelity AI Models</a> <font color="#6f6f6f">WSJ</font>
Knowledge Map
Connected Articles โ Knowledge Graph
This article is connected to other articles through shared AI topics and tags.
More in Releases

็ผๅญๆถๆๆทฑๅบฆๆๅ๏ผๅฆไฝ่ฎพ่ฎก้ซๆง่ฝ็ผๅญ็ณป็ป
<h1> ็ผๅญๆถๆๆทฑๅบฆๆๅ๏ผๅฆไฝ่ฎพ่ฎก้ซๆง่ฝ็ผๅญ็ณป็ป </h1> <blockquote> <p>ๅจ็ฐไปฃๅๅธๅผ็ณป็ปไธญ๏ผ็ผๅญๆฏๆๅ็ณป็ปๆง่ฝ็ๆ ธๅฟ็ปไปถใๆฌๆๅฐๆทฑๅ ฅๆข่ฎจ็ผๅญๆถๆ็่ฎพ่ฎกๅๅใ็ญ็ฅไธๅฎๆๆๅทงใ</p> </blockquote> <h2> ไธบไปไน่ฆไฝฟ็จ็ผๅญ๏ผ </h2> <p>ๅจ่ฝฏไปถ็ณป็ปไธญ๏ผ็ผๅญ็ๆฌ่ดจๆฏ<strong>็จ็ฉบ้ดๆขๆถ้ด</strong>ใ้่ฟๅฐ้ข็น่ฎฟ้ฎ็ๆฐๆฎๅญๅจๅจ้ซ้ๅญๅจไป่ดจไธญ๏ผๅๅฐๅฏนๆ ข้ๆฐๆฎๆบ็่ฎฟ้ฎๆฌกๆฐ๏ผไป่ๆพ่ๆๅ็ณป็ปๅๅบ้ๅบฆใ</p> <p>ๅ ธๅๅบๆฏ๏ผ</p> <ul> <li>ๆฐๆฎๅบๆฅ่ฏข็ปๆ็ผๅญ</li> <li>APIๅๅบ็ผๅญ</li> <li>ไผ่ฏ็ถๆ็ผๅญ</li> <li>่ฎก็ฎ็ปๆ็ผๅญ</li> </ul> <h2> ็ผๅญๆถๆ่ฎพ่ฎกๅๅ </h2> <h3> 1. ็ผๅญๅฑ็บง็ญ็ฅ </h3> <p>็ฐไปฃ็ณป็ป้ๅธธ้็จๅค็บง็ผๅญๆถๆ๏ผ<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ CDN (่พน็ผ็ผๅญ) โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ Redis/Memcached โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ ๆฌๅฐ็ผๅญ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค โ ๆฐๆฎๅบ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ </code></pre> </div> <p><strong>ๅๅ<

How to Use the ES2026 Temporal API in Node.js REST APIs (2026 Guide)
<p>After 9 years in development and countless TC39 meetings, the JavaScript Temporal API officially reached <strong>Stage 4 on March 11, 2026</strong>, locking it into the ES2026 specification. That means it's no longer a proposal โ it's the future of date and time handling in JavaScript, and you should start using it in your Node.js APIs today.</p> <p>If you've ever shipped a date-related bug in production โ DST edge cases, wrong timezone conversions, silent mutation bugs from <code>Date.setDate()</code> โ you're not alone. The <code>Date</code> object was designed in 1995, copied from Java, and has been causing developer pain ever since. Temporal is the fix.</p> <p>This guide covers <strong>how to use the ES2026 Temporal API in Node.js REST APIs</strong> with practical, real-world patter

Axios Hijack Post-Mortem: How to Audit, Pin, and Automate a Defense
<p>On March 31, 2026, the <code>axios</code> npm package was compromised via a hijacked maintainer account. Two versions, <code>1.14.1</code> and <code>0.30.4</code>, were weaponised with a malicious phantom dependency called <code>plain-crypto-js</code>. It functions as a Remote Access Trojan (RAT) that executes during the <code>postinstall</code> phase and silently exfiltrates environment variables: AWS keys, GitHub tokens, database credentials, and anything present in your <code>.env</code> at install time.</p> <p>The attack window was approximately 3 hours (00:21 to 03:29 UTC) before the packages were unpublished. A single CI run during that window is sufficient exposure.<br> This post documents the forensic audit and remediation steps performed on a Next.js production stack immediatel



Discussion
Sign in to join the discussion
No comments yet โ be the first to share your thoughts!