I always like seeing implementations that start from trial division and gradually introduce optimizations like wheel factorization.
It makes the trade-offs much clearer than jumping straight to a complex sieve.