Happy belated new year, everyone! I posted my 2024 In Review blog a week ago. Now it’s time to look forward to the remaining ~10-11 months of this year.
As with last year’s My Plans for 2024, this post is 40% a reference for anybody curious about my work… and 60% a form of self-motivation.
General Goals
My general 2025 goal is to make it as easy as possible to have great web development tooling. The primary ways I will do that are:
- Continue to maintain or otherwise contribute to impactful projects such as ESLint, Mocha, typescript-eslint, and Yeoman
- Build the best repository templating engine possible: Bingo
- Onboard create-typescript-app to that engine
- Consolidate common issue and pull request linting tasks into a GitHub-focused linter: Glint
- Increase the power and simplicity of developer tooling provided by create-typescript-app
- Stabilize tooling that converts from JavaScript to TypeScript and TypeScript to better TypeScript: ts-lift
- Socialize great developer tooling with Boston TS Club and SquiggleConf
Open Source
I’m a full time independent open source maintainer. I spend a majority of my time maintaining open source libraries I’m responsible for, as well as contributing to other libraries.
Finances
See my 2024 income breakdown in 2024 Finances in Review.
I took in a total income of roughly $60,191 for 2024. $46,561 of that was for open source work.
My high-level financial goal for 2025 is to grow my total income by ~25% to $75,000. I believe I can hit that through:
- Open source (~75%): growing ~25% from ~$46.5k to ~$58.2k
- Other work (~25%): growing ~20-25% from ~$13.6k to ~$16.8k
~$58.2k a year for open source is ~$4,850 a month. I think I can hit that through:
- typescript-eslint: $1,500 a month, or roughly 20% more than the current $1,250 a month
- ESLint: $1,000 a month, or 20 hours of $50/hour invoiced time
- Mocha: $700 a month, or 14 hours of $50/hour invoiced time
- Yeoman: $400 a month, as new income via Tidelift and thanks.dev
- GitHub Sponsors: $600 a month, slightly more than the current ~$500 a month
- Tidelift: $500 a month, doubling the current ~$250 a month
- thanks.dev: $150 a month, doubling the current ~$75 a month
~$16.8k a year for other work is a little over ~$1,400 a month. I think I can hit that through:
- Learning TypeScript book sales: $500 a month, or $6,000 for the year
- Podcasting: $600 a month, or $7,200 for the year
- Miscellaneous consulting or workshops: about $3,600 for the year
- Consulting will be my backup if any other source falls short
I’d prefer to not consult at all. But my open source sponsorships are not likely to increase enough to hit my total income goal.
Larger Projects
These ecosystem-level projects are high visibility to many web developers. My work in pushing them forward helps make their areas of development incrementally better. It’s fun and humbling to think about.
typescript-eslint
I’m on the typescript-eslint maintainer team. Unlike 2024, I don’t plan on pushing for any major user-facing changes. I’d like 2025 to be a more calm year for my typescript-eslint involvement.
Documentation
Objective: Rework the website to better explain the project.
Objective: Publish ≥4 long-requested blog posts.
The landing page on typescript-eslint.io hasn’t been reworked in a long time. It prioritizes explaining what ESLint and TypeScript are over the benefits or definition of typescript-eslint. @ElianCodes led me through an audit of typescript-eslint.io last year. I’d like to apply the suggestions from that audit to the typescript-eslint website.
Additionally, many longstanding community gripes about typescript-eslint and typed linting come in part from us not explaining ourselves well. I want us to have published at least 4 more blog posts that answer frequent user questions. At the very least, that should include:
- typescript-eslint#7350 Docs: Add blog post & revamped docs for parserOptions.projectService
- typescript-eslint#8517 Blog: Add post about our suite of Promise rules
Issue Management
Objective: Finish the year with <250 issues
Objective: Close out ≥3 of 4 issues from 2019
Objective: Close out ≥20 of 26 issues from 2019-2020
We started 2024 with about 400 open issues in our backlog and ended with just under 300 open issues. I don’t like having many hundreds of issues in a backlog.
Some old issues might be reasonable to keep open but not important enough for us to prioritize. But having too many old issues inevitably crowds out important ones. The more issues exist, the less likely any one issue will be addressed.
I’d like to continue shrinking the backlog by ending 2025 with just under 250 open issues, or 50 fewer than what we have now.
We still have 26 issues from many years ago: 22 from 2020 and 4 from 2019. I’d also like to get through at least 75% of those.
ESLint
Objective: Consistently work as an ESLint team member.
I’m on the ESLint committer team. I still don’t have any big flashy goals around ESLint. For my second year I just want to be a good, reliable member of the team.
If I consistently apply >15 hours a month to ESLint, and the work is an acceptable quality, I’ll be happy.
Mocha
Objective: Provide first-party TypeScript types with Mocha
Objective: Release Mocha 12 with long-pending small breaking changes
Objective: Release the new Mocha website
I’m on the new Mocha maintainer team (mocha#5027 📌 Project Status: Maintenance Reboot). 2024 was mostly a “pick up the pieces” year for Mocha.
For this second year I’m ready to make more impactful changes. The biggest is mocha/milestone/66 v12.0.0: releasing a new major version with actual breaking changes. Fixing old annoyances and removing long-deprecated features will be good for the project but technically requires a new major version.
Separately, mocha#4154 🚀 Feature: TypeScript .d.ts type declarations is the single most requested issue people bring up with me when they hear I took on Mocha maintenance.
Lastly, I made a new version of the ancient Mocha website using Astro last year: mocha#5246 docs: add new website using Astro Starlight.
I’d like to get that website fully launched this year, with the old website kept on something like old.mochajs.org
.
Yeoman
Objective: End 2025 having triaged and reviewed all Yeoman issues and pull requests older than a week
Objective: Clean up all known out-of-date information on yeoman.io
Objective: Update
yo
and other packages to no longer print deprecation warnings when run
I joined the Yeoman maintenance reboot in January! 🎩
Our goal is to keep Yeoman afloat. We don’t plan on releasing any major breaking changes or earth-shattering new features. We mostly want to keep the project up with the basic expectations developers have around running tools.
Bingo
Objective: Create in-memory, Handlebars-based, and Blocks-based templating systems
Objective: Create an automated repository migration flow based on GitHub Actions
Objective: Release a well-documented Bingo v1
The Bingo project -formerly named create
- is my take on a templating engine.
Its feature set represents points that I think no existing engine comes close to capturing a majority of:
- Ability to swap pieces of tooling in and out
- Migrations to newer template versions
- Test-friendly APIs for in-memory template creations
- Well-typed options through a standard schema (Zod)
I find all that very exciting: especially the “Blocks” system I’d originally envisioned for it (create-typescript-app#1181 📝 Documentation: Long-term project vision). Also automated migrations, so I don’t have to keep manually updating old repositories to new tooling config files.
create-typescript-app
Objective: Release a stable create-typescript-app@v2 built on Bingo
Objective: Reduce root files from 19 to 16
Objective: Support monorepos
Objective: Close out 14 of the 19 open issues I’d filed through 2022 and 2023.
As of writing, create-typescript-app is almost ready to promote a v2 version rebuilt on Bingo from beta to stable. It’s only blocked on a few foundational rearchitectures in Bingo.
Firstly, I aim to continue reducing the number of root-level files produced by the template. Tooling fatigue is a real problem for web developers. Every file added to repositories contributes to that fatigue. I’m pretty sure I can get rid of three config files from CTA:
.markdownlint.json
and.markdownlintignore
: create-typescript-app#1926 🚀 Feature: Use@eslint/markdown
instead of markdownlint.all-contributorsrc
: create-typescript-app#1930 🚀 Feature: Use all-contributors (or an equivalent) without creating a root-level file (.all-contributorsrc)
I’m also targeting two goals for 2025 that are carried over from My Plans for 2024 > create-typescript-app.
The biggest one is monorepo support.
I personally want CTA monorepo support for my own monorepos such as emoji-blast and TypeStat (ts-lift
).
The CTA issue tracker still has 19 issues from 2022 or 2023, 9 of which are features.
4 of those issues are status: blocked
, leaving 15 issues that I should be able to close out.
Adding a safe buffer of 1 issue leaves me with a goal of resolving 14 issues, or ~75% of the 19.
Glint
Objective: Make a stable lint experience for GitHub repositories — including issues and pull requests
Onboard Glint to be used in
create-typescript-app
This section is copied over from My Plans for 2024 > Standalone GitHub Linter.
One of the biggest pain points I’ve had in managing GitHub repositories is standardizing practices around comments, issues, and pull requests:
- Comments: not being obvious spam, including alt text for accessible images, …
- Issues: additionally: filling out required information, ensuring the title isn’t the default, …
- Pull requests: additionally: ensuring the PR addresses an open accepted issue, asking users not to force push, …
create-typescript-app
uses a few dedicated GitHub Actions to enforce some of those needs for now.
But that’s inconvenient.
I’d like to make a generalized linter for all those needs.
It will be configurable with granular rules, plugins, and shared configs like a typical linter.
I haven’t started deep design work on Glint. But I’m confident I can make it a shining example of repository tooling.
TypeStat (ts-lift
)
Objective: Rebrand, re-document, and stabilize TypeStat as a
ts-lift
monorepo.Objective: Create a
ts-initialize
project withints-lift
that reliably converts projects from JavaScript to TypeScript.Objective: Create a
ts-enhance
project withints-lift
that reliably improves TypeScript types when possible.
This section is partially copied over from My Plans for 2024 > TypeStat (ts-lift
).
Two factors make me more confident in tackling TypeStat this year:
create-typescript-app
being much more fleshed out and stable, with monorepo support planned for20242025.- Resolving TypeStat’s “Find a new name for this library” issue: Knowing that I’m going to split it into:
ts-lift
for the general package namets-initialize
for the onboarding portion (“JavaScript to TypeScript”)ts-enhance
for the types improving portion (“TypeScript to better TypeScript”)
That better understanding of how to split up the project means I can really think through the architecture and documentation.
Splitting ts-initialize
and ts-enhance
out of the shared core means I can focus them on doing their respective tasks.
…and, as much as I hate to cave to tech trend hype, it’s possible that ts-enhance
could use AI to solve type generation challenges that would otherwise be prohibitively difficult.
We’ll see.
Other Projects
These projects aren’t widely known names the way the larger ones. They’re smaller time investments that I think are valuable in their own right.
eslint-plugin-expect-type
Objective: Get adopted by DefinitelyTyped.
This section is partially copied over from My Plans for 2024 > eslint-plugin-expect-type.
eslint-plugin-expect-type
is a handy ESLint plugin that allows enforcing ^?
twoslash assertion comments and the like.
In 2024 I’d expanded the plugin to encompass all the features I know DefinitelyTyped-tools uses in its @definitelytyped/expect
equivalent.
I think it’d be great to reduce lint rule duplication and onboard DefinitelyTyped to the same rule as other consumers in the ecosystem.
eslint-plugin-package-json
Objective: Finish achieving feature parity with other package.json linters
I adopted the ESLint plugin for package.json
files in 2023 because I wanted to flesh out its feature set.
Some rules exist in other package.json linters that are not yet available in eslint-plugin-package-json
.
You can see the full list of linter rules in eslint-plugin-package-json#42 📌 Tracking issue: comparison with equivalent other tools.
For 2025, I’d like to finish filling out that list of rules.
This will involve creating granular APIs in package-json-validator
, another project I adopted.
Mint
Objective: Publish a blog post fully describing my idealized general web linter
Objective: Prototype a general web linter with first-class support for cross-file linting
I’m not going to compete with ESLint in 2025. typescript-eslint is not going anywhere anytime soon. I’m burying this project goal deep in this blog post because I don’t want anybody to misread and think this is some big ecosystem competitor or drama.
ESLint is structurally focused on single-file linting: each lint rule is architecturally encouraged to only think of one rule at a time. Single-file linting falls apart when you add typed linting. See eslint/rfcs#102 feat: parsing session objects.
I think any modern web linter needs first-class support for cross-file linting.
ESLint’s rewrite is positioned as the place for ESLint to work on that.
Native speed linters are working on it, too: e.g. Biome’s noFloatingPromises
rule.
I want to help work on cross-file linting — but have found it difficult to propose ideas given my lack of experience of actually writing a linter. And even for the ideas I’m confident in, not having a proof-of-concept linter to show my ideas working is a further detriment.
So, I plan on finally writing my own fresh, modern linter in 2025. 😱.
I’m first going to publish a blog post explaining all my ideas for what a modern web linter could do. See JoshuaKGoldberg/dot-com#296 🚀 Feature: Blog post on “If I Wrote a Linter”. That issue is blocked by a chain of other blog posts explaining nuances such as JoshuaKGoldberg/dot-com#297 🚀 Feature: Blog post on why I’d write a linter in TypeScript.
Other Packages
Objective: Maintain a small suite of well-managed open source repositories in my areas of interest.
This section is copied over from My Plans for 2024 > Other Packages).
I don’t exclusively work on my larger visibility projects: I also have a collection of smaller utilities.
They’ve all been onboarded to create-typescript-app
.
I plan on further onboarding those packages to Bingo’s automated tooling updates.
I’m also a committer or maintainer on a few other packages that I didn’t make and generally enjoy helping out with, such as dedent
and node-emoji
.
I don’t plan on leading any major changes for them: just keeping them well-maintained.
Community Engagement
It’s invaluable for open source maintainers to engage with other developers. We get previous user feedback and project exposure — especially when we’re a known name.
Conferences
Objective: Give all conference talks I’m happy with.
As noted in 2024 in Review > Conferences, I’m holding steady at giving a conference talk every 1-2 months. My goal is to be happy with the content and quality talks I’m giving.
As of writing this post I’m scheduled for 4 in-person conferences through June. I don’t plan on adding more than 1-2 additional in-person conference talks.
Blogging
Objective: Publish at least one blog post every three weeks
Objective: Publish at least one post in each blog every three months
I have a few blogs under my purview:
- My main personal blog at joshuakgoldberg.com/blog
- Learning TypeScript’s blog at learningtypescript.com/articles
- typescript-eslint’s blog at typescript-eslint.io/blog
I missed my blog post goals in both 2023 In Review > Goal: Branding and Blogging and 2024 In Review > Blogging. For this year I’m reducing the target numbers by about a third.
Boston TS Club
Objective: Produce ten successful monthly meetups for Boston TS Club
Objective: Create and keep schedules for those meetups
Objective: Step down as “director” and eliminate the singular leadership role
Boston TS Club is Boston’s monthly meetup for TypeScript and other web development areas. I’m very happy with how it’s going: see 2024 in Review > Boston TS Club.
For the meetups, my main hope for 2025 is to keep doing more of the same, but more organized. We’d like to turn our gained knowledge into more predictable meetups: e.g. publishing the timing of talks and networking sessions ahead of time.
Running a meetup is an investment of both time and emotional energy. I also hope to move away a sole “director” role the way I run it now. Instead, we’re looking to:
- Give each organizer autonomy and ownership over their area, with “understudies” who also learn the area
- Have the “director” role cycle between organizers every few months, to share experience gains and responsibility
My goal for 2025 is to make Boston TS Club able to run smoothly even if any organizer -including and especially myself- leaves.
SquiggleConf
Objective: Successfully run SquiggleConf 2025 without any major problems
Objective: Get 150 peak attendance
Objective: Break even 💸
Objective: Don’t burn out
SquiggleConf is Boston’s yearly conference for web development tooling. I’m very happy with how it’s going: see 2024 in Review > SquiggleConf.
My primary conference goal here is for nothing terrible to happen. Running a large event is scary. There are a lot of moving parts to contend with.
2024 saw about 125 attendees throughout the day. Now that we have more brand recognition and local ties, I’d like to grow to 150.
2024 came out to a deficit of several thousand dollars. I think we can at least break even in 2025, hopefully positioning ourselves to least make back our 2024 money within 2026.
Lastly, and perhaps most important for me personally, I don’t want to burn out again in 2025. 2024’s post-SquiggleConf burnout wrecked my productivity and impacted my personal health through October and much of November. I’m optimistic that with the awesome team, as well as starting conference work several months earlier in the year, I’ll avoid spending a month overeating ramen and re-watching Mad Men.
Personal
Personal happiness and health are key to sustainable development. These goals are largely copy & pasted from My Plans for 2024 > Personal.
Goal: Health
Objective: Eat healthy, balanced meals most days of the week
Objective: Reliably work out about three times a week
This section is partially copied over from My Plans for 2024 > Goal: Health.
I still aim for the roughly the same goals as last year:
- Wake up before 7am on weekdays and 8am on weekends at least 6 days a week
- Average 8 hours of work a day & 40 hour weeks
- I can go over for time-sensitive work, but need to compensate within a few days
- Eat three balanced, healthy meals a day at least 6 days a week
- Work out at least three times a week
- Date night with my spouse at least once a week
My stress gets worse when I’m stressed by work and/or the awful nation-wide events happening around me. The former I can control. The latter I cannot control, and am trying to separate out from work as much as possible for my mental health.
Goal: Personal Accountability
Objective: Have confidence in the amount of work I’ve accomplished.
Objective: Feel good about the amount of work I’ve accomplished.
I have a tendency to be self-critical and drive myself to the point of burnout. I also tend to undervalue the magnitude of work I’ve accomplished.
I used to keep a tracking Notion database & board for tasks and promise myself I’d review my performance using them. That was a surface-level “band-aid” fix for deeper insecurities.
This year, I’m going to try to center myself and address the root cause. I have a new therapist who is helping me connect with my emotions. If I get done most of what I say I want to in this post, I want to also feel good about about that.
We’ll see.
Out of Scope
I’m not going to tackle any of the points from My Plans for 2024 > Out of Scope:
- Conferences galore: I enjoy conferences, but doing too many of them is exhausting and takes time away from my other work
- Twitch streaming: similarly exhausting and it’s hard to tackle higher-scoped work than small bugfixes and features during it
- Older personal projects: work-life balance is important and I want to stay away from coding in my personal time
I just can’t justify the time expenditure.
Stretch Goals
Procrastination is one of my toxic traits. I’m very good at motivating myself to do something when it’s more shiny than what I’m supposed to be doing. Keeping a supply of “wouldn’t this be nice?” projects helps me stay productive.
The biggest top-of-mind projects for me are simplifications to the create-typescript-app template:
- Moving CSpell into ESLint: thereby removing the
cspell.json
file - Removing
.nvmrc
in favor ofpackage.json
"engines"
- Replacing
husky
+lint-staged
with a simpler system - Replacing tsup with a zero-config builder
No guarantees these will happen anytime soon. But it’s nice to dream.
Closing Thoughts
I’ve got a lot of objectives for 2025. I think the big splashy ones are doable as long as I focus on one each month or two and hold overflow time at the end of the year:
- February and March: Bingo and
create-typescript-app
- April: Glint
- May: Mint
- June: TypeStat (
ts-lift
) - July: Mocha, Yeoman, and other packages
- August and September: SquiggleConf
- October-November: overflow
Even if I don’t make all of those goals, it’s going to be an exciting year! 🙌
If you read this far - thank you, and I have no idea why. Let me know!