I remember back when I was a computer science student, talking with a classmate. We discussed whether or not it was a better idea for our instructor to give us a program with the part missing that was relevant to the lession, and have us fill in the missing piece, or to make us write each program from scratch. The former case allowed us to work on a complex program in a limited amount of time; the latter case helped us learn how to configure a project from scratch without skipping steps.
At the time, I felt that working on a larger program was more valuable. I suspected that in the working world, I'd be contributing to a lot more projects than I would be creating. I was more right than I knew.
Most of the programs that I've worked on have been legacy programs with a tenure of several years. The project that I spend most of my time on now is a web application with a code base that's nearly 10 years old. Throughout my career, I've met programmers who hate working on legacy code. They speak with mocking contempt of anything over a few years old and favor of newer languages and platforms. However, sometimes I smell fear underlying this contempt. Legacy code is scary. When you create a project from scratch, you know what is lurking in every corner. Inheriting someone else's code means you are going to run into surprises.
Legacy code isn't always bad code. Like anything updated and maintained over time, the quality is in the complex history of the product. Legacy code has been tested through use. Old languages that stick around stick around because they work. In some cases, like that of Java, they succeed because a productive ecosystem has grown up around them to aid in the full development lifecycle. A new, short-lived platform never develops these tools. A house that has been poorly maintained will eventually collapse; sometimes catastrophically. A house that has been maintained and expanded with care continues to be functional and contains pieces of well-thought out architecture and craftsmanship.
Personally, I like working on legacy code. At times, I feel like an archaeologist. You'll see examples of coding styles that were in vogue as you peel through the layers built up over the years. It means that sometimes you will be forced to go off into the world looking for information about a library-- perhaps a perfectly serviceable library, perhaps one you're forced to use-- that was released 5 years ago and stopped being supported 2 years ago. You'll crusade through the mocking sniggers on forums where you go to seek help. But you'll be helping a customer with their set of priorities and their budget, instead of a developer's need to try the latest tool. And you're likely to learn something: that the latest development trends are sometimes just a repackaging of concepts buried in legacy code.