If they're using collaborative filtering, there probably isn't a simple explanation. Basically, you feed in a list of "<user id>, <book id>, <rating>" and the algorithm generates a feature vector for each book and each user. So the reason some book gets recommended is because... the dot product of that book's vector with your vector was high. You can do this easily with off-the-shelf libraries, like Surprise[1] (I'm using that lib in my startup[2]).
At least this is what happens in matrix factorization methods. Recommendations from k-nearest neighbor methods can be explained more easily, but knn doesn't scale as well.
This is a minor drawback of matrix factorization--people have been shown to trust recommendations more if they understand how the recommendations were generated. Twitter recently published a super interesting paper[3] about how they generate recommendations at scale, and as a bonus their method is explainable. They create a model that describes the communities in Twitter--groups of people who follow the same set of influencers. Users and items are represented by vectors, where each element of a vector describes to what degree a user/item fits in a certain community. When generating recommendations, you can get the user's top communities and then fetch items for those communities. If you generated a text description for each community, you could include that with each recommendation.
[1] https://github.com/NicolasHug/Surprise
[3] https://www.kdd.org/kdd2020/accepted-papers/view/simclusters...