At first glance,
cy.fixture() seem fairly similar, both read files asynchronously and wrap them as Cypress usually does.
The main difference is conceptual, but there are some practical considerations as well.
Fixtures are meant for files that are used only for your tests, e.g. placeholder test data, sample responses and so forth. In other terms, fixtures are files that would not be a part of your project if you didn’t have tests.
For this end, fixtures provide some additional convenience, such as piping them directly into
cy.route('GET', '/users', 'fixture:users');
readFile() on the other hand is a generic method that you can use to read more or less anything. It is a good candidate if you need to read files that are a part of your regular project code, e.g. translations: