You may be mixing a few things together:
- leaflet is a presentation tool, it gets rendered client side - meaning you need to get all your data to your user's browser, where it gets processed and presented. This means that it is not always a good choice for heatmap kind of situations, when a lot of point data has to be transferred and rendered client side.
- the (in)famous Google API key used in {ggmap} is not as hard a showstopper as may seem. First of all it can be obtained relatively easily, and the free plan is generous. Secondly the Google Maps basemap, while certainly most popular and eponymous with the package, is not the only one supported.
- if interactivity is desired you may consider applying a grid of sort over your area of interest, and render the heatmap not directly from your point data, but from count of points over grid (which is what I did in the Czech page linked earlier) - this is more efficient in terms of data transferred, and you have more control over the end product with stuff like resolution or what not.
Anyhow, regarding the "free" aspect of ggmap: consider this piece of code, building on earlier post about Galapagos Islands, but updated for the fact that Stamen Maps no longer live on Stamen but on Stadia (it is a long story). Running it requires no payment nor registration, and it may be enough for your use case.
library(ggmap)
# download the basemap from Stadia
galapagos <- get_stadiamap(bbox = c(left = - 91,
bottom = -1.0,
right = -89.8,
top = -0.18),
zoom = 10,
maptype = "stamen_toner")
points <- data.frame(x = c(-90, -90.5, -90.25), # some random points...
y = c(-0.5, -0.8, -0.3))
ggmap(galapagos) + # the base map
geom_point(data = points, aes(x = x, y = y),
color = "red") # standard ggplot2 syntax