본문으로 건너뛰기
cccskills
무료GitHub에 공개

web-utilities-native-js

Modern native JavaScript (ES2022-ES2025) utility patterns that replace lodash

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(6)

  • SKILL.md8.5 KB
  • examples/arrays.md7.7 KB
  • examples/core.md4.5 KB
  • examples/objects.md5.3 KB
  • metadata.yaml344 B
  • reference.md7.4 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Native JavaScript Utility Patterns

Quick Guide: Most utility-library calls now have a native equivalent with no bundle cost. The four that change how code is written are structuredClone for deep copies, the ES2023 immutable array methods (toSorted, toReversed, toSpliced, with), Object.groupBy / Map.groupBy, and the ES2025 Set operations. The two facts that catch people out: a structured clone drops prototypes and throws on functions, and the immutable array methods copy one level deep.

Detailed Resources:

  • examples/core.md — cloning, immutable updates, negative indexing, searching from the end
  • examples/arrays.md — deduplication, set operations, grouping, chunking, sorting, compacting
  • examples/objects.md — typed pick/omit/mapValues, deep merge, lookup maps, freezing
  • reference.md — lodash-to-native table, function utilities (debounce, throttle, memoize), availability

<critical_requirements>

Before writing utility code

Reach for the native method before adding a dependency. The lodash-to-native table in reference.md settles most of it in one lookup, and the native call ships nothing.

Deep-copy with structuredClone. A JSON round trip turns a Date into a string and a Map or Set into {}, and it does so silently — the failure surfaces later, at the first .getTime().

Use the to* array methods where the array is shared. sort, reverse and splice rewrite the array in place, so a function that "returns a sorted copy" with sort has changed its caller's data.

Convert to a Set before repeated membership checks. includes inside a filter is O(n²), and the difference shows up at a few thousand elements.

</critical_requirements>


Auto-detection: structuredClone, Object.groupBy, Map.groupBy, toSorted, toReversed, toSpliced, Array.prototype.with, findLast, findLastIndex, at(-1), Object.hasOwn, Object.fromEntries, Set.prototype.union, Set.prototype.intersection, Set.prototype.difference, symmetricDifference, isSubsetOf, isDisjointFrom, lodash alternative, native JavaScript utilities

Applies to:

  • Array work — deduplicating, grouping, chunking, flattening, sorting immutably, searching from the end
  • Object work — picking, omitting, merging, key/value transformation, lookup maps
  • Set algebra — union, intersection, difference, subset tests
  • Deep copying without a dependency
  • Hand-rolled function utilities — debounce, throttle, memoize, once

Handled elsewhere:

  • Date arithmetic, parsing and formatting — Date alone does not cover it
  • Reactive updates — these methods produce new references, and what consumes a new reference is the concern of whatever owns the state
  • Schema validation and runtime parsing — these utilities reshape data that is already trusted

<decision_framework>

Native or a dependency

Three cases, in order:

  • A native method exists — use it. The table in reference.md is the lookup.
  • No native method, but the implementation is ten lines — write it. chunk, pick, omit, compact, deepMerge, debounce, throttle, memoize and once are all in this skill, written out and typed.
  • The edge cases are the feature — take the dependency. A debounce with cancel, flush and leading/trailing edges; a deep merge with per-key array strategies; lazy evaluation over a dataset large enough that intermediate arrays matter. Reimplementing these badly costs more than the bytes.

</decision_framework>


<patterns>

Core patterns

Pattern 1: structuredClone for deep copies

Preserves Date, Map, Set, RegExp, typed arrays and circular references — everything a JSON round trip destroys.

const snapshot = structuredClone(state);
// Preserved: Date, Map, Set, RegExp, ArrayBuffer, circular refs
// Throws on: functions, DOM nodes, Proxy, symbols
// Silently lost: the prototype — a class instance clones to a plain object

Full code: examples/core.md


Pattern 2: Immutable array methods (ES2023)

Four to* methods return a new array where the classic method rewrote the old one.

items.toSorted((a, b) => a.price - b.price); // vs .sort()
items.toReversed(); // vs .reverse()
items.toSpliced(index, 1); // vs .splice()
items.with(index, { ...items[index], done: true }); // vs items[i] = x

The copy is shallow: the new array holds the same element objects, which is why the update above spreads before writing.

Full code: examples/core.md


Pattern 3: Object.groupBy and Map.groupBy (ES2024)

const byStatus = Object.groupBy(orders, (order) => order.status);
// { pending: [...], shipped: [...] } — null-prototype, values are `T[] | undefined`

const byCustomer = Map.groupBy(orders, (order) => order.customer);
// Map keyed by the object itself — use this when the key is not a string

Object.groupBy coerces the key to a string and returns a null-prototype object, so reach for Object.hasOwn(byStatus, key) rather than byStatus.hasOwnProperty(key).

Full code: examples/arrays.md


Pattern 4: Set operations (ES2025)

setA.union(setB);
setA.intersection(setB);
setA.difference(setB); // in A, not in B
setA.symmetricDifference(setB);
setA.isSubsetOf(setB);
setA.isSupersetOf(setB);
setA.isDisjointFrom(setB);

Each returns a Set, so spread when an array is wanted. The argument is any set-like with size, has and keys — a Map qualifies, a plain array does not.

Full code: examples/arrays.md


Pattern 5: Searching and indexing from the end

logs.findLast((log) => log.level === "error"); // ES2023, single pass
logs.findLastIndex((log) => log.level === "error");
items.at(-1); // ES2022, undefined when empty
"file.backup.txt".split(".").at(-1); // "txt" — strings too

Full code: examples/core.md


Pattern 6: Object.fromEntries as the transformation pivot

entries → map/filter → fromEntries covers pick, omit, invert, mapValues, mapKeys and array-to-lookup in one shape, so those helpers are four lines each rather than a dependency.

const keyed = Object.fromEntries(items.map((item) => [item.id, item]));
const withTax = Object.fromEntries(
  Object.entries(prices).map(([k, v]) => [k, v * 1.1]),
);
const passing = Object.fromEntries(
  Object.entries(scores).filter(([, score]) => score >= 90),
);

Full code: examples/objects.md

</patterns>

<red_flags>

Red flags

Breaks at runtime:

  • structuredClone on anything holding a function, a DOM node or a Proxy throws DataCloneError — clone the data separately from the behaviour.
  • JSON.parse(JSON.stringify(x)) does not throw; it corrupts. A Date becomes a string, a Map or Set becomes {}, undefined members vanish, and the first method call on the result is where it surfaces.
  • Object.groupBy returns a null-prototype object, so result.hasOwnProperty(...) throws. Use Object.hasOwn.
  • Set methods reject a plain array — they need something with size, has and keys.

Surprising behaviour:

  • structuredClone discards the prototype. A class instance clones to a plain object with the same fields and none of the methods.
  • toSorted() with no comparator sorts by string, so [10, 9, 1].toSorted() is [1, 10, 9] — exactly as sort() always did.
  • The to* methods copy one level. Editing an element of the new array edits the same object in the old one.
  • arr.at(-1) types as T | undefined whatever the compiler options, so the empty case has to be handled. arr[arr.length - 1] types as T unless noUncheckedIndexedAccess is on — that is the form that lets an undefined flow on unchecked.
  • structuredClone on an Error succeeds and keeps the standard fields, but a code, a status or anything else attached to it is not in the copy.
  • filter(Boolean) drops 0, "" and false along with the nullish values, and TypeScript does not narrow the result — filter((x): x is T => x != null) does both jobs correctly.
  • Object.freeze is shallow, and outside strict mode a write to a frozen object fails silently rather than throwing.
  • Object.keys returns integer-like keys first in ascending numeric order, whatever the insertion order — only string keys keep insertion order.

</red_flags>

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Hugging Face Inference SDK patterns for TypeScript/Node.js — InferenceClient setup, chat completion, text generation, streaming, embeddings, image generation, audio transcription, translation, summarization, and Inference Endpoints

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

LiteLLM proxy server setup, TypeScript client patterns via OpenAI SDK, model routing, fallbacks, load balancing, spend tracking, virtual keys, and production deployment

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Serverless GPU compute platform for AI model deployment — web endpoints, GPU functions, model serving, and TypeScript client patterns

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Local LLM inference with the Ollama JavaScript client -- chat, streaming, tool calling, vision, embeddings, structured output, model management, and OpenAI-compatible endpoint

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Replicate SDK patterns for TypeScript/Node.js -- client setup, predictions, streaming, webhooks, file handling, model versioning, deployments, and training

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

Together AI SDK patterns for TypeScript — client setup, chat completions, streaming, structured output, function calling, embeddings, image generation, fine-tuning, and OpenAI-compatible endpoints

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

agents-inc/skills252026년 10월 17일 업데이트

agents-inc의 스킬 모두 보기

이 스킬의 문제 신고