Exclusive tips every week

Join 13,567+ other Vue devs and get exclusive tips and insights delivered straight to your inbox, every week.

    Picture of Michael Thiessen

    πŸ‘‹Hey friend! I work hard to send you amazing stuff each week.

    β€”Β Michael

    I really love and enjoy reading these emails.

    You are one of the most pro VueJS devs I know, and I am happy that you share this knowledge.

    Fabian Beer

    Here's my latest newsletter

    πŸ”₯ (216) Component design patterns, Nuxt's new data layer, and more

    Hi!

    If you like design patterns, I've got something great for you.

    A free, 5 day mini-course that covers 5 different patterns for writing better components.

    You can get more details and sign up for it here:

    Component Design Patterns

    I also wrote up a detailed blog post about the new data fetching in Nuxt 3.17:

    Nuxt’s Data Layer Has Been Rewritten: 5 New Features You Need to Know

    No new podcast episode this week, but we've got a couple great episodes coming soon!

    Have a great week!

    β€” Michael

    πŸ”₯ Structuring Composables

    To keep your composables β€” those extracted functions written using the composition API β€” neat and easy to read, here's a way to organize the code.

    1. Component and directives
    2. provide and inject
    3. defineProps, defineEmits, and defineExpose (when using script setup)
    4. refs and reactive variables
    5. Computed properties
    6. Immediate watchers
    7. Watchers
    8. Lifecycle methods, in their correct order
    9. Non-reactive state
    10. Methods
    11. Async code using await (or Promises if you're into that sort of thing)

    Why this order? Because it more or less follows the order of execution of the code.

    It's also based on the this linting rule.

    πŸ”₯ A bunch of composable mini tips

    Yes, mini tips within a tip. It's meta.

    Here they are:

    • Start with the end in mind, and write the return first. Once you know how you want the composable to be used, filling in the implementation details is much easier.
    • Use an options object as the parameter. This makes it easy to add new parameters in the future without breaking anything, and you won't mess up the ordering anymore.
    • Keep them small. Embrace the UNIX philosophy and make sure each composable only does one thing but does it well.
    • Name them consistently: use___
    • Always make sure your reactivity is hooked up before any async logic. By using a ref of null, you can update those values later when your logic completes. No need to await around.
    • Use effectScope to group effects if you have lots of them in your composable. This makes cleaning up your reactivity a lot simpler.
    • If you have large objects, use shallowRef instead to prevent Vue from recursively making the whole thing reactive. Of course, you'll need to use triggerRef to trigger any reactive effects for it, but it can improve performance.

    Some tips on making your composables more flexible:

    • If you're using a watch, make immediate and flush configurable
    • Accept both refs and primitive values as inputs. By passing the variable through ref, you'll either reuse the existing ref or create a new one.
    • The same trick works with unref if what you need in your composable is a primitive and not a ref.

    πŸ”₯ Inline Composables

    You can define composables inline, keeping them in your SFC file:

    <script setup>
    const useCount = (i) => {
    const count = ref(0);
    const increment = () => count.value += 1;
    const decrement = () => count.value -= 1;
    return {
    id: i,
    count,
    increment,
    decrement,
    };
    };
    const listOfCounters = [];
    for (const i = 0; i < 10; i++) {
    listOfCounters.push(useCount(i));
    }
    </script>
    <template>
    <div v-for="counter in listOfCounters" :key="counter.id">
    <button @click="counter.decrement()">-</button>
    {{ counter.count }}
    <button @click="counter.increment()">+</button>
    </div>
    </template>

    But is there any point to doing this?

    If you’re keeping your components focused on a specific task (and you should be), then it stands to reason that the logic is also focused on a single task.

    This means that if you wrap up all relevant logic into an inline composable, you’ve wrapped up all β€” or nearly all β€” the logic that this component has:

    <script setup>
    // Create an inline composable
    const useStuff = () => {
    <all_our_logic>
    };
    // ...only to destructure most of it to use in our template
    const {
    value,
    anotherValue,
    eventHandler,
    anotherEventHandler
    } = useStuff();
    </script>

    At which point, we might as well write our logic without that unnecessary wrapper:

    <script setup>
    const value = ...
    const anotherValue = ...
    const eventHandler = ...
    const anotherEventHandler = ...
    </script>

    However, if you have do have logic that can be encapsulated nicely within this inline composable, it could make your code cleaner and easier to use.

    Using lexical scoping to create more boundaries within your files helps you to understand and think through your code, which is always helpful.

    πŸ“œ 21 Nuxt Tips You Need to Know

    In this article I share 21 tips for working with Nuxt.

    These are tips and tricks that I've found useful, and I think every Nuxt developer should know.

    We cover a lot of topics here, including:

    • When to use /assets vs. /public directory
    • Using runtimeConfig vs. app.config
    • Understanding how Universal rendering works (and how it's different from SPA and SSR)

    Check it out here: 21 Nuxt Tips You Need to Know

    πŸ“œ My Favourite Nuxt Features

    In this article I explore several features of Nuxt that I think are the most interesting.

    This will give you a good overview of why Nuxt is so great to work with.

    Check it out here: My Favourite Nuxt Features

    πŸ“… Upcoming Events

    Here are some upcoming events you might be interested in. Let me know if I've missed any!

    VueConf US 2025Β β€”Β (May 13, 2025 to May 15, 2025)

    VueConf US 2025 is a great Vue conference, this year held in Tampa from May 13–15, with two days of talks and a day of workshops. Unfortunately, I am no longer able to make it to the conference this year. I hope everyone attending has an amazing time and I look forward to joining in the future!

    Check it out here

    MadVue 2025Β β€”Β (May 29, 2025)

    It's time to get together in Madrid. Join for a full day of talks, activities, and networking with the Vue.js community and ecosystem.

    Check it out here

    πŸ’¬ Things

    "Things aren’t always #000000 and #FFFFFF." β€”Β undefined

    🧠 Spaced-repetition: Performance Tracing

    The best way to commit something to long-term memory is to periodically review it, gradually increasing the time between reviews πŸ‘¨β€πŸ”¬

    Actually remembering these tips is much more useful than just a quick distraction, so here's a tip from a couple weeks ago to jog your memory.

    Vue allows you to do performance tracing to help you debug any performance issues:

    const app = createApp({});
    app.config.performance = true;

    Once you do this, you can use the official Vue Devtools to debug your app's performance.

    Michael Hoffman curates a fantastic weekly newsletter with the best Vue and Nuxt links.

    Sign up for it here.

    p.s. I also have a bunch of products/courses:

    Here's what others are saying

    I'm starting to think that your newsletter is one of the best things that happened to me this year. I just love these emails.
    Stanislaw Gregor
    I'm somewhere in the upper-middle level at Vue, and I never miss an email you and always find something cool when reading!
    Eduard Climov
    This is the first time where I'm actually enjoying email newsletters. I like your format a lot.
    Fahmi Alfituri
    You have great content in your emails. I seriously learn something from every one of them.
    Titus Decali
    Just wanted to say I enjoy these emails. They encourage me to constantly improve my craft. Fantastic work.
    Joe Radman
    Thanks for another beautiful tip πŸ™
    Victor Martins Onuoha
    Loving these, and the spaced repetition.
    Mark Goldstein
    I really enjoy reading your emails, because I love Vue. Thanks for these emails.
    Arturo Espinoza
    I really love and enjoy reading these emails. You are one of the most pro VueJS devs I know, and I am happy that you share this knowledge.
    Fabian Beer
    THANK YOU! I did not know about the deep property, so I assumed you simply couldn't watch objects.
    Darryl Noakes
    I really must say you are doing a really great job. Now I am aware of a cleaner and more performant way to use Tailwind. Thanks a lot!
    Henry Eze
    Thank you so much, I really enjoy and appreciate your emails.
    Carlos Gonzalez
    Thanks for sharing great Vue tips.
    Fernando Navarro
    I really enjoy these tips.
    Martin H
    Thank you so much for the weekly Vue education. Thanks and live on longer to educate us more.
    Kabolobari Benakole
    I look forward to your emails every week. This week was something I knew, but I like to be reminded of. Thanks for keeping it up!
    Nathan Strutz
    Thank you for your weekly emails. I always look forward to learning a new tip about Vue or at least relearning old tips :)
    Colin Johnson
    I have really been enjoying your weekly emails, and I also got my two team members to join in on the fun as well.
    Keith Dawson
    Thank you for your newsletter, your explanations have very concise examples and I like it.
    Nicolas Decayeux
    Thanks A LOT for your great work!!! One of the few newsletters that I let pass!
    Martin Tillmann

    Want to level up your Vue skills?

    With over two million reads and 11,067 subscribers, you've come to the right place.

    Subscribe now to get exclusive insights and tips every week.