Preheat the oven to 350°F (177°C) and line a 12-cup muffin pan with cupcake liners.
In a large bowl, whisk together the 1 ⅓ cups (166g) all-purpose flour, ¾ teaspoon baking powder, ¾ teaspoon baking soda, ½ teaspoon salt, 1 teaspoon cinnamon, ½ teaspoon ginger, and ¼ teaspoon nutmeg. Set aside.
In a separate bowl, whisk the ½ cup (120ml) vegetable oil, ⅔ cup (150g) packed brown sugar, ⅓ cup (65g) granulated sugar, 2 large eggs, ¼ cup (60g) sour cream or Greek yogurt, ¼ cup (59ml) whole milk and 2 teaspoons vanilla extract until smooth, then stir in the 1 ½ cups (200g) peeled, finely shredded, and coarsely chopped carrots. Add the wet ingredients to the dry ingredients and gently fold or whisk until fully combined. The batter will be slightly thick. Gently stir in the ⅔ cup (77g) chopped walnuts or pecans if using.
Spoon the batter into the prepared liners, filling each about ¾ full to prevent overflow. Bake for 20–23 minutes, or until a toothpick inserted in the center comes out clean. For mini cupcakes (about 30), bake for 12–13 minutes at the same temperature. Let the cupcakes cool completely before frosting.
To make the frosting, beat the 8 ounces (224g) full-fat block cream cheese and 1/2 cup (8 Tbsp; 113g) unsalted butter together in a large bowl using a handheld or stand mixer fitted with a paddle or whisk attachment until smooth and creamy. Add the 3 cups (360g) powdered sugar, 1 teaspoon pure vanilla extract, and 1/8 teaspoon salt. Beat on low speed for 30 seconds, then increase to high speed and beat for about 2 minutes. Cover and refrigerate the frosting while the cupcakes cool. This is especially helpful if you plan to pipe it, as chilled cream cheese frosting holds its shape better.
Frost the cooled cupcakes and add any garnishes you like. I used an Ateco 808 piping tip and finished the swirl with a small icing spatula, but any decorating style works. Store leftover cupcakes covered in the refrigerator for up to 5 days. A cupcake carrier works great for storing and transporting decorated cupcakes.