- Published on
Tools and Trends to Avoid in 2026 — A Curated Anti-Recommendation Deep Dive
- Authors

- Name
- Youngju Kim
- @fjvbn20031
This is not a "stop using these" rant. It is a curated list of tools and trends that, as of 2026, I no longer recommend — paired in every case with what to use instead. Opinions, but with receipts.
Prologue — Why we need anti-recommendations
There are plenty of articles about good tools. Articles that tell you which tools to leave are rarer, for two reasons. First, criticizing someone's nostalgia and someone's working software is unpopular. Second, tools never live in a vacuum, so any "this is bad" claim is almost always only partly true.
Someone still has to write it. The tutorial a 2026 new hire finds first is often stuck in 2018, and half of the tools that tutorial recommends are no longer maintained. Starting a new project on that path means broken builds in the first week, piling security advisories in the first month, and a migration bill in the first quarter.
Premises of this article:
- Every tool was right at some point. Criticism does not erase that.
- The cost equation flips over time. Eventually "what this tool prevents" outweighs "what this tool did."
- Criticism without alternatives is lazy. Every item below ships with a replacement.
- The replacements are not eternal either. In a year, half of this article will need rewriting.
That last premise matters. Read this as guidance — "if I were starting a new project today, where would I not start?" — not as scripture.
1. The matrix at a glance — AVOID / INSTEAD
A map before the territory.
| Category | AVOID | INSTEAD | One-line reason |
|---|---|---|---|
| Frontend bootstrap | Create React App | Vite / Next.js / TanStack Start | CRA was officially un-recommended in 2023; effectively retired in 2025 |
| Date handling | Moment.js | date-fns / Day.js / Temporal | Moment's own team calls it "a legacy project" |
| Utility library | Full lodash import | Standard ES / per-function / Bun built-ins | Tree-shaking loss, standards caught up |
| Node package manager | Yarn 1 | pnpm / Bun / Yarn 4 | Yarn 1 receives no real updates |
| Bundler | Standalone Webpack / Gulp builds | Vite / Rspack / Turbopack / Bun | Single-digit-ms cold starts and HMR |
| Monorepo | Yarn Workspaces alone | pnpm + Turborepo / Nx | Caching and impact analysis are now table stakes |
| Python tooling install | apt-get install python | uv / pipx / mise | Stop polluting the system Python |
| Python deps | pip install -r requirements.txt | uv / Poetry / Hatch | Real lockfiles and parallel installs |
| AI eval | Open LLM Leaderboard | LMArena / Artificial Analysis | Archived in 2024-2025 |
| LLM integration | LangChain <v0.2 deep imports | Split langchain-* packages / LlamaIndex / direct SDKs | The deep paths themselves moved |
| Prompting | "You are an expert in..." preambles | System prompt + spec + evals | Frontier models stopped rewarding generic flattery |
| Observability | AppDynamics / heavy APM | OpenTelemetry + Grafana / Tempo | One standard, no lock-in |
| Log shipping | Custom forwarder + custom format | OTel collector + structured JSON | Standards are leverage |
| CI | Travis CI (OSS-free era over) | GitHub Actions / GitLab CI / Buildkite | Travis ended the OSS free tier |
| Container builds | Unauthenticated Docker Hub pulls | Internal mirror / ECR / GHCR / cache | Pull limits break your build SLA |
| Secrets | Committed .env, plaintext sharing | SOPS / Doppler / Vault / SealedSecrets | The #1 single-cause incident |
| Editor | VS Code "install everything" | Extension diet, vetted publishers only | Supply chain and performance, simultaneously |
| Collaboration | "No review, push to main" | Short PRs + fast review + merge queues | A team that never reviews stops learning |
The table is long on purpose. The point is not the item but the pair. "Not Moment" is not the lesson — "not Moment, instead date-fns/Temporal" is.
2. Frontend — CRA, Moment, full lodash imports
2.1 Create React App
What went wrong. CRA shipped from Facebook in 2016 as the one-line bootstrap for React. It abstracted dependencies and a Webpack 4 config, which lowered the on-ramp dramatically. But maintenance effectively stopped in 2022, the official React docs deprecated it for new apps in March 2023, and the React team posted an explicit sunset notice in 2025. Cold starts climb into tens of seconds to minutes, security advisories pile up, and the path to new React features (server components, streaming, the App Router) does not run through CRA anymore.
Why people still reach for it. Search results take them there. Tutorials written between 2018 and 2022 still rank at the top, and internal company docs froze around the same time. New hires follow the path.
Use instead.
- Single-page app:
Vite + React. Sub-second cold starts, instant HMR. - Full-stack / routing / server components:
Next.js. The de facto React meta-framework. - Routing-first SPA with a thin server:
TanStack Start. Type-safe router and data loading.
Credit where due. CRA defined "one command to start" for React. The default-friendliness of every successor is its legacy.
2.2 Moment.js
What went wrong. Moment was the de facto JavaScript date library. But its mutable object model, large bundle, full locale bundling, and non-tree-shakable surface clash with modern frontend values. Decisively, the Moment team declared it "a legacy project" in September 2020: no new features, only critical fixes.
Why people still reach for it. The old code already imports it. And the alternatives are plural enough to cause decision paralysis.
Use instead.
date-fns: functional, tree-shakable, widest interoperability. Default choice for formatting and arithmetic.Day.js: API-compatible with Moment. Lowest migration cost.Temporal: an ECMAScript proposal in late stages. Adoptable today via polyfill. This is where the world is going.Luxon: from a former Moment maintainer. More opinionated.
Credit where due. Without Moment, working with Date for a decade would have been worse than it already was. It bought time for the standard to catch up.
2.3 Full lodash import
What went wrong. import _ from 'lodash' pulls the whole library into the bundle. By 2026 the standard has absorbed about half of lodash: Array.prototype.at, structuredClone, Object.groupBy, Array.fromAsync, Promise.any, Promise.allSettled, String.prototype.replaceAll, optional chaining, nullish coalescing. lodash itself has had effectively no major updates since 4.17.21 in 2021.
Why people still reach for it. Old code and old muscle memory. _.get, _.pick, _.debounce are habit-shaped.
Use instead.
- Prefer the standard whenever possible.
- Deep access: optional chaining and nullish coalescing.
- If you still need a specific lodash function, import from
lodash-esper-function:import { debounce } from 'lodash-es'. - On Bun, check the runtime built-ins first.
Credit where due. lodash's documentation was, for years, the de facto reference for the JavaScript standard library.
2.4 Gulp / Grunt / Bower
What went wrong. Bower formally announced "we are done" in 2017 and pointed users at npm/yarn. Gulp/Grunt had real value when bundlers were less capable, but as Webpack and successors absorbed the pipeline, their footprint shrank. In 2026, encountering a new project on Gulp is rare.
Use instead.
- Bundle/HMR:
Vite,Rspack,Turbopack,Bun. - Task runners:
package.jsonscripts +npm-run-all/concurrently/turbo run.
Credit where due. "Builds are code" was their gift. The idea survived; only the tools changed.
3. Node toolchain — Yarn 1, lone Workspaces, hand-rolled Webpack
3.1 Yarn 1
What went wrong. Yarn 1 was the hero of 2017-2020: it fixed npm's worst issues at the time. But Yarn 2+ split off into the Berry line, and 1.x became effectively frozen aside from security work. The bigger issue is the flattened node_modules strategy, which allows accidental dependency resolution — exactly what pnpm solved.
Use instead.
- General single project:
pnpm. Disk-efficient, strict resolution. - Monorepo:
pnpm workspaces + TurborepoorNx. - Speed:
Bun. Fast install and run, broadening compatibility. - If you love Yarn itself:
Yarn 4(Berry, with PnP ornodeModulesLinker). Vet PnP compatibility before committing.
3.2 Running a monorepo on Yarn Workspaces alone
What went wrong. Workspaces themselves are fine. But a monorepo without a build cache, impact analysis, or remote caching collapses quickly. Once humans start deciding "what does this PR need to rebuild?", you have lost.
Use instead.
Turborepo: simple config, JS/TS-centric.Nx: more powerful graph and plugins. Polyglot or large org.Bazel: very large org, polyglot. Only when you can afford the learning curve.
3.3 Hand-rolled webpack.config.js
What went wrong. Webpack is not bad. But in 2026, sitting down to author a custom Webpack config — every loader, every plugin, by hand — is almost always a loss. Vite and Turbopack took most of that ground, and Rspack (Rust-based, Webpack-compatible) is catching the rest.
Use instead.
- New projects:
Vite,Next.jsbuilt-in,Turbopackvia Next. - Existing Webpack assets you do not want to rewrite:
Rspack. Keep the config, gain the speed.
Credit where due. Webpack defined "frontend build" as a concept. The mental model — entries, loaders, plugins — lives on in every successor.
4. Python — system Python, lone requirements.txt, conda overuse
4.1 apt-get install python (or brew install python) used as a tooling install
What went wrong. The system Python is part of the operating system. pip install into it breaks OS tooling in ways that are painful to recover. "Always use a venv" is a fine rule, but a rule humans hand-enforce is finished.
Use instead.
uv(Astral): Rust-based fast Python project manager. Quick resolution, install, and lockfiles by default. The new de facto standard since 2024-2025.pipx: install CLI-style Python tools (black,httpie) into isolation.miseorasdf: pin Python versions per project. Faster thanpyenv, polyglot-friendly.
4.2 requirements.txt alone with pip freeze
What went wrong. pip freeze > requirements.txt is a snapshot of an environment, not a specification of dependencies. Direct deps and transitive deps merge, platforms collapse together, and "works on my machine" returns.
Use instead.
uv'spyproject.toml+uv.lock. Direct deps and lockfile are separate; cross-platform locks supported.Poetry: opinionated experience. Popularized lockfiles for Python.Hatch: builds and environment management aligned with PEPs.
4.3 conda for everything
What went wrong. conda shines when your science stack is heavy and full of native libraries. For pure Python web apps or CLIs, dependency resolution drags into minutes, channel conflicts appear, and Anaconda's commercial-channel policies add license risk to enterprise use.
Use instead.
- Pure Python:
uvorPoetry. - Science / ML / native:
mamba(fast conda-compatible) orpixi(Rust-based, conda-package aware, integrates lockfiles and tasks).pixiis gaining ground fast in 2024-2026.
Credit where due. conda was the first tool that made GPU stacks installable without an OS package manager — and that gift is still real for the right workload.
5. AI eval and LLM integration — Open LLM Leaderboard, old LangChain, stale prompt tricks
5.1 Open LLM Leaderboard
What went wrong. Hugging Face's Open LLM Leaderboard was the de facto standard for open-model evaluation in 2023-2024. But the original eval set (MMLU, ARC, HellaSwag, TruthfulQA, Winogrande, GSM8K) saturated quickly, and parts of it leaked into training data. Hugging Face migrated to v2 in June 2024, then placed v2 itself into an archive state during 2025. Fresh scores no longer appear.
Use instead.
LMArena(formerly Chatbot Arena): pairwise human preference, Elo-style ranking. The single most reliable "which model is better" signal.Artificial Analysis: quality vs. price vs. latency, side by side. Useful for actual procurement.- Domain benchmarks:
SWE-benchfor software engineering,LiveCodeBenchfor contamination-resistant coding,MMLU-Profor harder reasoning,GPQAfor graduate-level science. - Internal eval: every team needs a golden set of its own. The above narrow the candidate field; your set picks the winner.
5.2 Pre-v0.2 LangChain deep imports
What went wrong. LangChain code from 2023-2024 often reached deep — from langchain.something.deep.path import X. From v0.2 onward, the package was split into langchain, langchain-core, langchain-community, integration-specific langchain-openai, langchain-anthropic, and langgraph for agent graphs. Most of those deep paths broke.
Why people still reach for it. Old tutorials still rank, new hires copy-paste them, and the v0.2+ migration guide is long enough to defer.
Use instead.
- If you keep LangChain, import from the integration-specific packages and use
langgraphfor agent topologies. - For simple calls, skip LangChain and use the official SDKs (Anthropic, OpenAI, Google). The abstraction often costs more than it pays.
- Retrieval and indexing:
LlamaIndex— surface is more consistent. - Multi-agent orchestration: weigh
LangGraph,CrewAI,OpenAI Swarm. The fancier the abstraction, the harder the debugging.
Credit where due. LangChain crystallized the idea of "wiring an LLM into code." It also had to reshape itself repeatedly while best practices solidified, which is why old and new look so different.
5.3 "You are an expert in X" preambles and friends
What went wrong. In 2022-2023, prefixes like "You are a senior engineer, think step by step, take a deep breath" really did help. As models were RLHF-aligned and trained on tool use, the marginal value of those generic preambles collapsed. Since 2025, the major vendors' prompting guides ask for specification, not flattery.
Use instead.
- System prompts that specify role, constraints, prohibitions, output format. Not "expert" — "produce auditable SQL, no comments, single transaction".
- Change prompts against an eval set. Numbers, not vibes.
- Long system prompts hurt cache hit rate and context cost. Short, sharp, structured.
- If you need chain-of-thought, replace "think step by step" with explicit steps and an output schema (JSON Schema).
Credit where due. Not every old trick was empty. "Let's think step by step" had real effect once, and that observation seeded the entire reasoning-models line. Tricks were absorbed into training.
6. Observability and infrastructure — heavy APM, custom forwarders, Docker Hub habits
6.1 AppDynamics / Dynatrace on a small stack
What went wrong. Full-stack APMs make sense for large enterprise monoliths. For a five-person team with ten microservices, license cost and operational drag outweigh the value, and vendor lock-in is real.
Use instead.
- The standard is OpenTelemetry (OTel). One spec for metrics, logs, traces.
- Metrics:
Prometheus+Grafana. - Traces:
TempoorJaeger. - Logs:
Lokior a cloud-native equivalent. - For hosted bundles:
Grafana Cloud,Honeycomb. Evaluate hosting cost separately. - If you genuinely need an integrated commercial product:
Datadog,New Relic. Benchmark by their OTel compatibility.
6.2 Custom log forwarder, custom format, custom pipeline
What went wrong. "Our own log format" is fast for six months and slow for six years. Every new tool needs an adapter, and search, retention, and storage all become DIY.
Use instead.
- Format: structured JSON, keys aligned with
OpenTelemetry semantic conventions. - Forwarder:
OpenTelemetry CollectororVector(open source from Datadog). - Storage: managed, or
ClickHouse/OpenSearch. Build it yourself as a last resort.
6.3 Pinning your build SLA to anonymous Docker Hub pulls
What went wrong. Docker Hub has applied rate limits on unauthenticated/free pulls since 2020. When CI hits the limit, builds fake-fail. You also trust upstream base images with no separate verification.
Use instead.
- Internal mirror:
Harbor,JFrog Artifactory, or a cloud registry (ECR,GHCR,Artifact Registry). - Pull base images through the mirror; verify SBOM and signatures (
cosign). - Make multi-architecture targets explicit (
amd64/arm64).
7. DevOps and CI — Travis OSS, hand-rolled bash, push-to-main
7.1 Pinning an OSS project's CI to Travis
What went wrong. Travis CI built the OSS-free CI era. Their post-2020 policy change made many OSS projects effectively unable to keep using it. Starting a new OSS project on Travis in 2026 makes very little sense.
Use instead.
- Most common:
GitHub Actions. OSS minutes generous enough for almost everything. - Strongest caching/parallelism:
Buildkite(self-hosted agents),CircleCI. - GitLab shops:
GitLab CI. - Monorepos:
Turborepo/Nxcaching layered on any of the above.
7.2 Hand-written bash as the core of your build
What went wrong. Bash is powerful and ubiquitous. Bash scripts over 100 lines almost always pick the wrong abstraction. The person who knows the env vars leaves; the env vars go with them.
Use instead.
- Simple command bundles:
package.jsonscripts,mise tasks,just. - Build graphs:
Turborepo,Nx,Bazel. - When a bash script gets long, that is the signal to migrate to a tool. 200 lines is a number, not a goal.
7.3 "Push to main" culture
What went wrong. This is a process anti-pattern, not a tool one. Small teams move fast that way — until they do not. Unreviewed merges are the first sign a team has stopped learning, and incidents arrive exactly on schedule.
Use instead.
- Short PRs (under roughly 400 lines changed) as a norm.
- Merge queues (
Mergify, GitHub Merge Queue) — prevent main breakage. - Auto-merge rules — review approved plus CI green equals merge.
CODEOWNERSplus a single-reviewer rule — route changes to people who care.
8. General process anti-patterns — VS Code extension bloat, .env in git, "let's rewrite"
8.1 VS Code extension bloat
What went wrong. VS Code's rich extension ecosystem is a strength. When it becomes a default — "looks useful, install it" — two things break at once. Performance (startup time, memory, language-server clashes) and supply chain (malicious extensions, typosquatting).
Use instead.
- Extension diet. Each quarter, remove what you do not use.
- Vet publishers:
Microsoft, official language teams, known companies. Anything else gets reviewed before install. - Workspace-recommended extensions (
extensions.json). - Different tools for different work. Heavy IDEs only when you really need them.
Credit where due. VS Code's extension model permanently changed the editor world. The problem is not the model, it is the lack of restraint.
8.2 Committed .env, plaintext secrets, tokens in chat
What went wrong. The single most common root cause of incidents. A committed secret is forever — even history rewrites do not reliably catch every copy.
Use instead.
- Local:
direnv+.envrc.local(never committed) +1Password CLI/op read. - Team:
SOPS+age/KMS,Doppler,1Password Secrets Automation. - Infrastructure:
Vault, cloud secrets managers (AWS Secrets Manager, GCP Secret Manager),SealedSecrets(Kubernetes). - Detection:
git-secrets,gitleaks,trufflehogin both pre-commit hooks and CI.
8.3 "It is old, let us rewrite everything"
What went wrong. The temptation to apply every recommendation in this article in one quarter. Big rewrites are the most expensive way to repay debt, and new debt accrues while the rewrite runs.
Use instead.
- Strangler-fig pattern: new code grows around old code until the old code is unreachable.
- Module-by-module migration, one at a time.
- A quarterly "replace one tool" goal. Four per year is a lot.
- Each migration logs before/after metrics (build time, bundle size, vulnerability count). Today's decision becomes tomorrow's evidence.
9. The gray zone — not dead, just not your default
This is not "never use these." These are tools that I would not pick as the default for a new project in 2026, but where context can justify them.
| Tool | Why not the default | Where it still fits |
|---|---|---|
| Jenkins | Self-host burden, plugin debt | Large internal estates, strict on-prem requirements |
| Vagrant | Docker/Devcontainers absorbed most cases | Genuine need for VM-level reproducibility |
| MongoDB by default | Transactions, schema, reporting weak | High-churn schemas plus throughput, true unstructured data |
| jQuery | Modern DOM + fetch handle most cases | Legacy systems, very simple pages |
| Bootstrap 5 by default | Out of step with token-and-utility-first design | Internal tools that need to ship without a design system |
| Selenium | Playwright/Cypress are the modern default | Old grid investments, non-standard browsers |
| Hand-tuned Nginx | Caddy/Envoy are more modern defaults | Precise tuning, large existing assets |
Gray-zone honesty matters. "Not the default, but rational here" is a real category. Tools live in context.
10. A short eulogy for what they got right
Before the wake, the toasts.
- CRA turned "starting React" from a research project into one command. Every successor's default-friendliness inherits its legacy.
- Moment.js filled a decade-long gap in the JavaScript date API and bought time for the standard to catch up.
- lodash doubled as the de facto reference manual for the JS standard library — the example list the standard now lives up to.
- Webpack defined "frontend build" as a category. The mental model is inherited by Vite, Rspack, Turbopack.
- Jenkins popularized CI culture.
- Travis CI opened the OSS-CI free tier era.
- LangChain named the pattern of wiring LLMs into code, and reshaped itself many times to keep the road clear for everyone else.
- AppDynamics invented the full-stack APM category.
Criticism's partner is gratitude. Today's better tools stand on roads these tools paved.
Epilogue — A one-quarter checklist and the next post
If you can only do one thing this quarter
For a new project, take defaults from the matrix above and move on. For an existing project, replace the slowest step of the most frequently-run pipeline — and only that. Trimming a 30-minute step from a job that runs 100 times a week returns 50 hours per quarter.
Pre-adoption six-question checklist
- Is this tool maintained? Check the last release date and the closed-issue ratio.
- What is the official recommendation status? Look for words like "deprecated."
- Is there an alternative and migration path? Do not adopt locked-in.
- Is the bundle/runtime cost worth it? Do not add a dependency for what the standard now does.
- How is the supply chain risk handled? Extensions, plugins, and nodes are all third-party code.
- What is the exit cost? If you regret it in six months, can you get out?
Anti-patterns to remember
- Stopping at the first search result — 2018-2022 articles still rank first in half of all queries.
- "The team is used to it" — familiarity is an asset to one group and a liability to the next.
- "It has 10,000 stars" — stars are attention, not adoption.
- "We will rewrite next week" — big rewrites are the most expensive way to repay debt.
- Criticizing without alternatives — every item here pairs with one for a reason.
Coming next
The next post takes the migrations themselves seriously. CRA → Vite, Moment → date-fns/Temporal, Yarn 1 → pnpm, requirements.txt → uv: a working, step-by-step playbook with real code, what to break, what to defer, what to automate. The piece that turns the decision to migrate into a finished migration.
Accepting a tool's expiration date is not a defeat. It is the first move of the next decision.
References
- React docs, "Create React App is deprecated" — https://react.dev/learn/start-a-new-react-project
- React team blog, "Sunsetting Create React App" — https://react.dev/blog/2025/02/14/sunsetting-create-react-app
- Moment.js official notice, "Moment is now a legacy project" (September 2020) — https://momentjs.com/docs/#/-project-status/
- date-fns — https://date-fns.org/
- Day.js — https://day.js.org/
- TC39 Temporal proposal — https://tc39.es/proposal-temporal/docs/
- pnpm — https://pnpm.io/
- Bun — https://bun.sh/
- Yarn 4 (Berry) — https://yarnpkg.com/
- Turborepo — https://turbo.build/repo
- Nx — https://nx.dev/
- Vite — https://vite.dev/
- Rspack — https://rspack.dev/
- Turbopack — https://turbo.build/pack
- TanStack Start — https://tanstack.com/start
- Bower, "Bower is dead, long live npm" — https://bower.io/blog/2017/how-to-migrate-away-from-bower/
- uv (Astral) — https://docs.astral.sh/uv/
- pipx — https://pipx.pypa.io/stable/
- mise — https://mise.jdx.dev/
- Poetry — https://python-poetry.org/
- Hatch — https://hatch.pypa.io/latest/
- Pixi — https://prefix.dev/
- Hugging Face Open LLM Leaderboard v2 announcement — https://huggingface.co/spaces/open-llm-leaderboard/open_llm_leaderboard
- Hugging Face blog, "Open LLM Leaderboard archive" — https://huggingface.co/blog/leaderboard-archive
- LMArena — https://lmarena.ai/
- Artificial Analysis — https://artificialanalysis.ai/
- SWE-bench — https://www.swebench.com/
- LiveCodeBench — https://livecodebench.github.io/
- LangChain v0.2 migration guide — https://python.langchain.com/docs/versions/v0_2/
- LangGraph — https://langchain-ai.github.io/langgraph/
- LlamaIndex — https://docs.llamaindex.ai/
- OpenTelemetry — https://opentelemetry.io/
- Grafana Tempo — https://grafana.com/oss/tempo/
- Vector (Datadog open source) — https://vector.dev/
- Docker Hub pull-limit policy — https://docs.docker.com/docker-hub/usage/
- cosign (Sigstore) — https://docs.sigstore.dev/cosign/overview/
- Travis CI open-source policy change — https://blog.travis-ci.com/oss-announcement
- GitHub Actions — https://docs.github.com/actions
- SOPS (Mozilla) — https://github.com/getsops/sops
- Doppler — https://www.doppler.com/
- HashiCorp Vault — https://www.vaultproject.io/
- SealedSecrets — https://sealed-secrets.netlify.app/
- gitleaks — https://github.com/gitleaks/gitleaks
- trufflehog — https://github.com/trufflesecurity/trufflehog
- Playwright — https://playwright.dev/
- Cypress — https://www.cypress.io/
- Caddy — https://caddyserver.com/
- Envoy — https://www.envoyproxy.io/